20.1 shell腳本介紹
20.2 shell腳本結構和執行
20.3 date命令用法
20.4 shell腳本中的變量
20.5 shell腳本中的邏輯判斷
20.6 文件目錄屬性判斷
20.7 if特殊用法
20.8/20.9 case判斷
20.10 for循環
20.11/20.12 while循環
20.13 break跳出循環
20.14 continue結束本次循環
20.15 exit退出整個腳本
擴展
select用法 http://www.apelearn.com/bbs/thread-7950-1-1.htmlhtml
shell是一種腳本語言 和傳統的開發語言比較,會比較簡單shell
shell有本身的語法規則;可使用邏輯判斷、循環等語法編程
能夠自定義函數,目的就是爲了減小重複的代碼bash
shell是系統命令的集合less
shell腳本能夠實現自動化運維,能大大增長咱們的運維效率運維
shell腳本的格式:函數
開頭須要加#!/bin/bash 以#開頭的行做爲解釋說明 腳本的名字以.sh結尾,用於區分這是一個shell腳本
示例中執行腳本會先輸出123,在w查看系統負載,接着lsspa
執行腳本的方法:3d
一、sh 01.shhtm
二、給腳本文件增長可執行權限,也能夠執行
chmod a+x 01.sh ./01.sh //當前目錄下01.sh,相對路徑 或者用絕對路徑: /root/shell/01.sh
三、/bin/sh實際是bash的軟鏈接;實際上是真正執行的是bash
/bin/sh 01.sh bash 01.sh
-x 查看腳本執行過程 bash -x 01.sh
-n查看腳本是否語法錯誤 bash -n 01.sh ,沒有輸出表明沒有錯誤
去掉01.sh中的echo "123"的一個雙引號,執行報錯
經常使用格式
date +%Y-%m-%d, date +%y-%m-%d 年月日
date +%H:%M:%S = date +%T 時間
date +%s 時間戳
date -d @1504620492
date -d "+1day" 一天後
date -d "-1 day" 一天前
date -d "-1 month" 一月前
date -d "-1 min" 一分鐘前
date +%w, date +%W 星期
date //當前的日期 cal //日曆 date +%Y //大寫Y 年份2018 date +%y //小寫y 年份18 date +%m //小寫m 月份07 date +%Y%m%d //年月日20180729 date +%F //大寫F 日期格式2018-07-30 date +%H //大寫H 小時09 date +%M //大寫M 分鐘17 date +%S //大寫S 秒14 date +%s //小寫s 時間戳1532913453 date +%T //大寫T 常規時間09:17:53 date "+%Y-%m-%d %H:%M:%S %w" //所有時間列出 年月日 時分秒 星期
date -d "-1 day" //前一天的日期時間2018年 07月 28日 星期六 09:19:12 CST date -d "-1 day" +%F //帶格式的 前一天的日期時間2018-07-29 date -d "-1 month" +%F // 帶格式的 上一個月2018-06-29 date -d "-1 year" +%F //帶格式的 上一個月2017-07-29 date -d "-1 hour" +%T //上一小時的時間08:19:54 date +%s -d "2019-06-14 21:24:08" //查看其對應的時間戳1560518648 date -d @1560518648 把時間戳換算成日期
當腳本中使用某個字符串較頻繁而且字符串長度很長時就應該使用變量代替 使用條件語句時,常使用變量 if [ $a -gt 1 ]; then ... ; fi 引用某個命令的結果時,用變量替代 n=`wc -l 1.txt` 寫和用戶交互的腳本時,變量也是必不可少的 read -p "Input a number: " n; echo $n 若是沒寫這個n,能夠直接使用$REPLY 內置變量 $0, $1, $2… $0表示腳本自己,$1 第一個參數,$2 第二個 .... $#表示參數個數 數學運算a=1;b=2; c=$(($a+$b))或者$[$a+$b]
格式1:if 條件 ; then 語句; fi 格式2:if 條件; then 語句; else 語句; fi 格式3:if …; then … ;elif …; then …; else …; fi 邏輯判斷表達式:if [ $a -gt $b ]; if [ $a -lt 5 ]; if [ $b -eq 10 ]等 -gt (>); -lt(<); -ge(>=); -le(<=);-eq(==); -ne(!=) 注意處處都是空格
可使用 && || 結合多個條件
if [ $a -gt 5 ] && [ $a -lt 10 ]; then &&而且 if [ $b -gt 5 ] || [ $b -lt 3 ]; then ||或者
符號 |
釋義 |
對應單詞 |
-gt |
大於 |
greater than |
-lt |
小於 |
ess than |
-ge |
大於或等於 |
greater than or equal |
-le |
小於或等於 |
less than or equal |
-eq |
等於 |
equality |
-ne |
不等於 |
inequality |
格式1:if 條件 ; then 語句; fi
if [ $a -gt 3 ]; then echo ok; fi 若是a>3,那麼輸出ok
放到腳本中:
格式2:if 條件; then 語句; else 語句; fi
若是$a大於3,輸出ok,不然輸出no
格式3:if …; then … ;elif …; then …; else …; fi
#!/bin/bash read -p "請輸入考試分數:" a if [ $a -lt 60 ] then echo "太差勁了!重考,未經過考試!" elif [ $a -ge 60 ] && [ $a -le 85 ] then echo "還行吧!經過考試,成績良好!" else echo "恭喜你!經過考試,成績優秀! " fi
[ -f file ]判斷是不是普通文件,且存在
[ -d file ] 判斷是不是目錄,且存在
[ -e file ] 判斷文件或目錄是否存在
[ -r file ] 判斷文件是否可讀
[ -w file ] 判斷文件是否可寫
[ -x file ] 判斷文件是否可執行
判斷是不是普通文件,且存在: [ -f file ]
示例中判斷/tmp/下的tobe文件是否存在,若是存在,輸出/tmp/tobe exist,不存在則建立該目錄
判斷是不是目錄,且存在: [ -d file ]
若是/tmp下的tobe123不是目錄,mkdir建立,不然輸出/tmp/tobe123 exist
而且 &&
f="/root/ceshi" [ -f $f ] && rm -f $f //前一條命令執行成功纔會繼續執行以後的命令 等同於下面的表達方式 if [ -f $f ] then rm -rf $f fi
或者 ||
f="/tmp/ttt123.txt" [ -f $f ] || touch $f //前面命令不成功時,即文件不存在,纔會執行後面的命令,進行建立 等同於下面的表達方式 if [ ! -f $f ] // 「!」表示了若是這條命令不成功,就往下執行 then touch $f fi
圓括號與方括號的區別:
if (($a<1)); then … 等同於 if [ $a -lt 1 ]; then…
[ ] 中不能使用<,>,==,!=,>=,<=這樣的符號
#! /bin/bash n=`wc -l /etc/passwd |awk '{print $1}'` //輸出/etc/passwd的行數 if [ -z "$n" ] //條件:是否爲空 then echo error exit elif [ $n -gt 20 ] //條件:n是否大於20 then echo OK fi
if [ -n "$a" ] 表示當變量a的值不爲空,或者說這個文件內容不爲空
-n 判斷變量的時候,須要用""雙引號引發來,如果文件的時候,則不須要用雙引號引發來
if [ -n "$b" ]; then echo $b; else echo "b is null"; fi 若是$b不爲空,輸出$b,不然輸出b is null
-w精準匹配
-q 過濾,可是不顯示過濾內容
if grep -wq 'user1' /etc/passwd;then echo "user1 is exist";fi 若是匹配到user1時,輸出user1 is exist if ! grep -wq 'user1' /etc/passwd;then useradd user1;fi 若是匹配不到user1,則添加用戶user1
格式:
case 變量名 in value1) command ;; value2) command ;; *) commond ;; esac
案例
read -p "Please input a number: " n //read讓用戶輸入字符串,好比輸入了1,那麼n就會賦值1,即n=1
exit 1
#!/bin/bash read -p "Please input a number: " n //read讓用戶輸入字符串,好比輸入了1,那麼n就會賦值1,即n=1 if [ -z "$n" ] //判斷用戶有沒有輸入 then echo "Please input a number." exit 1 fi n1=`echo $n|sed 's/[0-9]//g'` //檢查用戶輸入的是否是所有是數字,不是數字就置空 if [ -n "$n1" ] then echo "Please input aa number." exit 1 fi if [ $n -lt 60 ] && [ $n -ge 0 ] //通過如上的篩選,咱們來判斷輸入數字屬於哪一個範圍,而且把值交給tag then tag=1 elif [ $n -ge 60 ] && [ $n -lt 80 ] then tag=2 elif [ $n -ge 80 ] && [ $n -lt 90 ] then tag=3 elif [ $n -ge 90 ] && [ $n -le 100 ] then tag=4 else tag=0 //大於100的狀況 fi case $tag in //根據如上獲得的值,進行判斷 1) 表示第一個條件 echo "not ok" 值爲1時,輸出此內容 ;; 2) echo "ok" 值爲2時,輸出此內容 ;; 3) echo "ok ok" ;; 4) echo "perfect" ;; *) * 表明除此以外的 echo "Pls input a number range 0-100" ;; esac
重複執行一系列命令在 編程中很常見。一般你須要重複一組命令直到達到某個特定條件,好比處理某個目錄下的全部文件、系統上的全部用戶或者是某個文本文件中的全部行。
常見的兩種循環,在腳本中廣泛被用到。
for循環
while循環
語法:for 變量名 in 條件; do …; done
示例一:累加求和
能夠看到運算過程
#!/bin/bash sum=0 for i in `seq 1 10` do echo "$sum + $i" sum=$[$sum+$i] echo $sum done echo $sum
直接計算
#!/bin/bash sum=0 for i in `seq 1 10` do sum=$[$sum+$i] done echo $sum
案例2
遍歷一個目錄或者文件
#!/bin/bashcd cd /etc/ //進入到目錄 for a in `ls /etc/` //遍歷此目錄 do [ -d $a ] && ls $a # 判斷是不是目錄,並列出其下文件和子目錄 if [ -d $a ] then echo $a ls $a fi done
for循環會以空格或回車爲分隔符
語法 while 條件; do … ; done
案例1:
每隔1分鐘檢查一下系統負載,當系統的負載大於10的時候,發一封郵件(監控腳本) 最小單元是任務計劃 cron
#!/bin/bash while : # 冒號 : 表示死循環的意思,或者1,或者 true都是死循環 do load=`w|head -1|awk -F 'load average: ' '{print $2}'|cut -d. -f1` if [ $load -gt 10 ] then /usr/lib/zabbix/alertscripts/mail.py foutt7777@163.com "load high" "$load" fi sleep 30 #休眠30秒,由於檢查系統負載,不須要一直去檢查,過一會再看 done
代碼名詞釋義
w :查看系統負載 ;
uptime 能夠直接顯示 w 系統負載的第一行,就能夠省去 head -1
head -1 //取第一行
awk -F 'load average: ' '{print $2}' // 以'load average: '分隔,輸出第二段
cut -d . -f1 // 以 . 分隔 取第一段
休眠30秒後會一直檢查
while循環案例2
在循環過程過,須要用戶輸入一個數字;輸入的不是數字或輸入爲空;迴應相應的結果
#!/bin/bash while : do read -p "Please input a number: " n if [ -z "$n" ] 若是內容是空的,那麼$n爲空;若是有內容,執行下面的n1=`echo $n|sed 's/[0-9]//g'` then echo "須要輸入." 那麼echo continue continue 從新回到循環,繼續執行上面的操做 fi n1=`echo $n|sed 's/[0-9]//g'` 判斷是不是純數字 if [ -n "$n1" ] ! -z = -n then echo "你只能輸入一個純數字." continue fi break break 退出循環 done echo $n
break 經常使用於循環語句中,跳出整個循環語句,直接結束全部循環。
#!/bin/bash for i in `seq 1 5` do echo A=$i if [ $i -eq 3 ] #比較數字,用-eq ;如果比較的是字符串,那須要用 == then break 等於3時,調出循環 fi echo B=$i done echo C=$i
#!/bin/bash for i in `seq 1 5` do echo A=$i if [ $i -eq 3 ] then continue fi echo B=$i done echo abc
注意沒有B=3行
exit能夠定義退出的數值,能夠用於肯定腳本運行到什麼地方的時候結束
#!/bin/bash for i in `seq 1 5` do echo A=$i if [ $i -eq 3 ] then exit fi echo B=$i done echo C=$i
直接從A=3退出