通過博文Shell腳本應用(一),可以在簡單的Shell腳本程序中,各類語句將按先後順序依次執行,從而實現批處理的自動化過程,然而,單一的順序結構使得腳本國語機械化,不夠“智能”,難以處理更加靈活的系統任務。
今天我們將認識並掌握如何進行條件測試操作,並通過正確使用if語句,使Shell腳本具有一定的“判斷”能力,以根據不同的條件來完成不同的管理任務。
一、條件測試操作
要使Shell腳本具有一定的“智能”,面臨的第一個問題就是如何區分不同的情況已確定執行何種操作。例如:當磁盤使用率達到某個點時,發出警告信息等操作。
Shell環境根據命令執行後的返回狀態值($?)來判斷是否執行成功,當返回值爲0時,表示成功;當返回值爲非0時,則表示失敗。使用專門的測試工具——test命令,可以對特定條件進行測試。
使用test測試命令時,兩種語法:
格式1:test 條件表達式
或者
格式2:[ 條件表達式 ]
這兩種方式的作用完全相同,但通常第二種語法格式較爲適用。
但是需要注意:第二種語法格式中括號“[ 條件表達式 ]”與條件表達式至少需要一個空格進行分隔!
根據需要測試的條件類型不同,條件表達式也不同,比較常用的條件操作包括:
1.文件測試
文件測試指的是根據特定的路徑,判斷對應的文件是目錄還是文件,或者是否可讀、可寫、可執行等操作。常用的選項有:
-d:測試是否爲目錄(Directory) -e:測試目錄或文件是否存在(Exist) -f:測試是否爲文件(File) -r:測試當前用戶是否有權限讀取(Read) -w:測試當前用戶是否有權限寫入(Write) -x:測試當前用戶是否有權限執行(eXcute)
執行條件測試操作以後,通過預定義變量$?來獲得測試命令的返回值,從而判斷該條件是否成立。比如:
[root@localhost ~]# [ -d /mnt ] //測試/mnt是不是一個目錄 [root@localhost ~]# echo $? //查看前一條命令的返回值 0 //0表示條件成立,非0則表示條件不成立
爲了更直觀的查看測試效果,可以結合“&&”和“echo”命令一起使用。比如:
[root@localhost ~]# [ -d /etc ] && echo "yes" yes //輸出“yes”表示條件成立,不輸出“yes”則表示條件不成立
2.整數值比較
整數值比較指的是根據給定的兩個整數值,判斷第一個數與第二個數的關係,比如等於、大於、小於等。常用的選項有:
-eq:等於(Equal) -ne:不等於(Not Equal) -gt:大於(Greater Than) -lt:小於(Lesser Than) -le:小於或等於(Lesser or Equal) -ge:大於或等於(Greater or Equal)
整數值比較在Shell甲苯編寫中的應用較多。例如,用來判斷已登錄用戶數量、開啓的進程數等。比如:
[root@localhost ~]# A=`who | wc -l` [root@localhost ~]# [ $A -eq 3 ] && echo "nice" nice //查看當前登錄用戶爲3的話輸出“nice”
3.字符串比較
字符串比較通常用力啊檢查用戶輸入、系統環境等是否滿足條件,在提供交互式操作的S我回來了腳本中,也可以用來判斷用戶輸入的位置參數是否符合要求。常用的參數有:
=:字符串內容相同 !=:字符串內容不同,! 號表示相反的意思 -z:字符串內容爲空
語法格式:
[ 字符串1 = 字符串2 ] [ 字符串1 != 字符串2 ] [ -z 字符串 ]
4.邏輯測試
邏輯測試指的是判斷兩個或多個條件之間的依懶關係。當系統任務取決於多個不同的條件時,根據這些條件是否同時成立或其中一個成立等情況,需要有一個測試過程,常用的參數有:
-a或&&:邏輯與,“而且”的意思 -o或||:邏輯或,“或者”的意思 !:邏輯否
語法格式:
格式1:[ 表達式1 ] 操作符 [ 表達式2 ] ... 格式2:命令1 操作符 命令2 ...
二、使用if語句結構
通過剛纔的條件測試可以完成簡單的判斷並執行相應的曹組,但是當需要選擇執行的命令語句較多時,這種方式會使代碼顯得複雜且不好理解。我們可以適當的使用if語句,來整理腳本結構,使得層次分明、清晰易懂。
1)if語句的結構
在Shell腳本應用中,if語句是最常用的一種流程控制方式,用力啊根據特定的條件測試結果,分別執行不同的操作(如果……那麼……)。根據不同的複雜程度,if語句的選擇結構可以分爲三種基本類型,適用於不同的應用場合。
1.單分支if語句
if語句的:“分支”指的是不同測試結果所對應的執行語句(一條或多條)。對於if但分支的選擇結構,只有在“條件成立”時纔會執行相應的代碼,否則不執行任何操作。
1)單分支if語句的語法結構:
if 條件測試操作 then 命令序列 fi
語句結構中,條件測試操作可以是“[ 條件表達式 ]”語句,也可以是其他可指定的命令語句,命令序列指的是一條或多條可執行的命令行,也包括嵌套使用的if語句或其他流程控制語句。
2)單分支if語句的流程圖:
3)單分支if語句應用示例:
[root@localhost ~]# vim a.sh //隨便定義腳本名稱 #!/bin/bash //聲明使用什麼Shell A="/mnt/cdrom" //定義變量 if //關鍵字(如果) [ !-d $A ] //$A變量不是一個目錄的話 then //關鍵字(那麼) mkdir -p $A //創建這個變量所對應的目錄 fi //關鍵字(結束) [root@localhost ~]# sh a.sh //執行腳本 [root@localhost ~]# ll /mnt 總用量 0 drwxr-xr-x. 2 root root 6 7月 30 12:19 cdrom //驗證效果
2.多分支if語句
對於多分支的選擇結構,要求針對“條件成立”、“條件不成立”兩種情況分別執行不同的操作。
1)雙分支if語句的語法結構:
if 條件測試操作 then 命令序列1 else 命令序列2 fi
2)雙分支if語句流程圖:
3)雙分支if語句應用示例:
[root@localhost ~]# vim b.sh #!/bin/bash ping -c 3 -i 0.2 -W 3 $1 &> /dev/null //檢查目標主機是否可以連通 if //關鍵字(如果) [ $? -eq 0 ] //測試上一條命令的返回結果 then //關鍵字(那麼) echo "Host $1 is up" else //關鍵字(否則) echo "Host $1 is down" fi //關鍵字(結束) #(註釋)代碼中,爲了提高ping命令的測試率,使用“-c”表示只發送三個測試包;“-i”表示間隔時間爲0.2秒;“-W”表示超時時間3秒。另外使用 “ &> /dev/null”屏蔽ping命令執行過程的輸出信息。 [root@localhost ~]# sh b.sh Host is down //執行腳本測試返回結果
3.多分支if語句
由於if語句可以根據測試結果的成立、不成立分別進行操作,所以能夠嵌套使用,進行多次判斷。
1)多分支if語句語法結構:
if 條件測試操作1 then 命令序列1 elif 條件測試操作2 then 命令序列2 else 命令序列3 fi
2)多分支if語句流程圖:
3)多分支if語句應用示例:
(1) 應用示例(一)
[root@localhost ~]# vim c.sh #!/bin/bash read -p "請輸入您的分數(0——100):" A if [ $A -ge 85 ] && [ $A -le 100 ] //85~100分,優秀 then echo "$A分,優秀!" elif [ $A -ge 70 ] && [ $A -le 84 ] //70~84分,及格 then echo "$A分,及格!" else echo "$A分,不及格!" //其他分數,不及格 fi [root@localhost ~]# sh c.sh 請輸入您的分數(0——100):66 66分,不及格! [root@localhost ~]# sh c.sh 請輸入您的分數(0——100):79 79分,及格! [root@localhost ~]# sh c.sh 請輸入您的分數(0——100):99 99分,優秀! //驗證執行腳本效果
(2)應用示例(二)
示例要求:
(1)使用df命令提取出根分區的磁盤佔用率,賦值給變量DUG。
(2)使用mpstat命令提取CPU使用率(需安裝sysstat軟件包),賦值給變量CUG。
(3)使用free命令提取出內存使用率,賦值給變量MUG。
(4)判斷上述監控項目是否超標,將需要告警的信息保存到/tmp/alert.txt文件。
(5)判斷/tmp/alert.txt文件是否存在,若存在則作爲告警郵件發送。
[root@localhost ~]# vim 1.sh #!/bin/bash # 提取性能監控指標(磁盤佔用、CPU使用、內存使用) DUG=$(df -hT | grep "/$" | awk '{print $6}' | awk -F% '{print $1}') CUG=$(expr 100 - $(mpstat | tail -1 | awk '{print $12}' | awk -F. '{print $1}')) MUG=$(expr $(free | grep "Mem:" | awk '{print $3}') \* 100 / $(free | grep "Mem:" | awk '{print $2}')) # 設置告警日誌文件、告警郵箱 ALOG="/tmp/alert.txt" AMAIL="root" # 判斷是否記錄告警 if [ $DUG -ge 0 ] then echo "磁盤佔用率:$DUG %" >> $ALOG fi if [ $CUG -ge 0 ] then echo "CPU使用率:$CUG %" >> $ALOG fi if [ $MUG -ge 0 ] then echo "內存使用率:$MUG %" >> $ALOG fi # 判斷是否發送告警郵件,最後刪除告警日誌文件 if [ -f $ALOG ] then cat $ALOG | mail -s "Host Alert" $AMAIL rm -rf $ALOG fi [root@localhost ~]# sh 1.sh [root@localhost ~]# mail //查看郵件 Heirloom Mail version 12.5 7/5/10. Type ? for help. "/var/spool/mail/root": 1 message 1 new N 1 root Tue Jul 30 13:01 20/662 "Host Alert" & …………………… //省略部分內容 磁盤佔用率:26 % CPU使用率:1 % 內存使用率:18 % //驗證結果 #(註釋)實驗環境,大於等於0就發送郵件,實際生產環境視情況而定!
也可以這樣查看郵件:
[root@localhost ~]# cat /var/spool/mail/root …………… //省略部分內容 磁盤佔用率:26 % CPU使用率:1 % 內存使用率:18 %
您在 /var/spool/mail/root 中有郵件