1、復合條件測試
if-then 語句允許你使用布爾邏輯來組合測試。有兩種布爾運算符可用:
- [ condition1 ] && [ condition2 ]
- [ condition1 ] || [ condition2 ]
第一種布爾運算使用AND布爾運算符來組合兩個條件。要讓then部分的命令執行,兩個條件都必須滿足。
布爾邏輯是一種能夠將可能的返回值簡化為TRUE或FALSE的方法。
第二種布爾運算使用OR布爾運算符來組合兩個條件。如果任意條件為TRUE,then部分的命令就會執行。
下例展示了AND布爾運算符的使用。
1 $ cat test22.sh
2 #!/bin/bash 3 # testing compound comparisons 4 # 5 if [ -d $HOME ] && [ -w $HOME/testing ] 6 then
7 echo "The file exists and you can write to it"
8 else
9 echo "I cannot write to the file"
10 fi
11 $ 12 $ ./test22.sh
13 I cannot write to the file
14 $ 15 $ touch $HOME/testing 16 $ 17 $ ./test22.sh
18 The file exists and you can write to it 19 $
使用AND布爾運算符時,兩個比較都必須滿足。第一個比較會檢查用戶的$HOME目錄是否存在。第二個比較會檢查在用戶的$HOME目錄是否有個叫testing的文件,以及用戶是否有該文件的寫入權限。如果兩個比較中的一個失敗了,if語句就會失敗,shell就會執行else部分的命令。如果兩個比較都通過了,則if語句通過,shell會執行then部分的命令。
2、 if-then 的高級特性
bash shell提供了兩項可在if-then語句中使用的高級特性:
- 用於數學表達式的雙括號
- 用於高級字符串處理功能的雙方括號
2.1、使用雙括號
雙括號命令允許你在比較過程中使用高級數學表達式。test命令只能在比較中使用簡單的算術操作。雙括號命令提供了更多的數學符號,這些符號對於用過其他編程語言的程序員而言並不陌生。雙括號命令的格式如下:
(( expression ))
expression可以是任意的數學賦值或比較表達式。除了test命令使用的標准數學運算符,下表列出了雙括號命令中會用到的其他運算符。
可以在if語句中用雙括號命令,也可以在腳本中的普通命令里使用來賦值。
1 $ cat test23.sh
2 #!/bin/bash 3 # using double parenthesis 4 # 5 val1=10
6 # 7 if (( $val1 ** 2 > 90 )) 8 then
9 (( val2 = $val1 ** 2 )) 10 echo "The square of $val1 is $val2"
11 fi
12 $ 13 $ ./test23.sh
14 The square of 10 is 100
15 $
注意,不需要將雙括號中表達式里的大於號轉義。這是雙括號命令提供的另一個高級特性。
2.2、使用雙方括號
雙方括號命令提供了針對字符串比較的高級特性。雙方括號命令的格式如下:
[[ expression ]]
雙方括號里的expression使用了test命令中采用的標准字符串比較。但它提供了test命令未提供的另一個特性——模式匹配(pattern matching)。
說明 雙方括號在bash shell中工作良好。不過要小心,不是所有的shell都支持雙方括號。
在模式匹配中,可以定義一個正則表達式來匹配字符串值。
1 $ cat test24.sh
2 #!/bin/bash 3 # using pattern matching 4 # 5 if [[ $USER == r* ]] 6 then
7 echo "Hello $USER"
8 else
9 echo "Sorry, I do not know you"
10 fi
11 $ 12 $ ./test24.sh
13 Hello rich 14 $
在上面的腳本中,我們使用了雙等號(==)。雙等號將右邊的字符串(r*)視為一個模式,並應用模式匹配規則。雙方括號命令$USER環境變量進行匹配,看它是否以字母r開頭。如果是的話,比較通過,shell會執行then部分的命令。
2.3、case 命令
你會經常發現自己在嘗試計算一個變量的值,在一組可能的值中尋找特定值。在這種情形下,你不得不寫出很長的if-then-else語句,就像下面這樣。
1 $ cat test25.sh
2 #!/bin/bash 3 # looking for a possible value 4 # 5 if [ $USER = "rich" ] 6 then
7 echo "Welcome $USER"
8 echo "Please enjoy your visit"
9 elif [ $USER = "barbara" ] 10 then
11 echo "Welcome $USER"
12 echo "Please enjoy your visit"
13 elif [ $USER = "testing" ] 14 then
15 echo "Special testing account"
16 elif [ $USER = "jessica" ] 17 then
18 echo "Do not forget to logout when you're done"
19 else
20 echo "Sorry, you are not allowed here"
21 fi
22 $ 23 $ ./test25.sh
24 Welcome rich 25 Please enjoy your visit 26 $
elif語句繼續if-then檢查,為比較變量尋找特定的值。
有了case命令,就不需要再寫出所有的elif語句來不停地檢查同一個變量的值了。case命令會采用列表格式來檢查單個變量的多個值。
1 case variable in
2 pattern1 | pattern2) commands1;; 3 pattern3) commands2;; 4 *) default commands;; 5 esac
case命令會將指定的變量與不同模式進行比較。如果變量和模式是匹配的,那么shell會執行為該模式指定的命令。可以通過豎線操作符在一行中分隔出多個模式模式。星號會捕獲所有與已知模式不匹配的值。這里有個將if-then-else程序轉換成用case命令的例子。
1 $ cat test26.sh
2 #!/bin/bash 3 # using the case command 4 # 5 case $USER in
6 rich | barbara) 7 echo "Welcome, $USER"
8 echo "Please enjoy your visit";; 9 testing) 10 echo "Special testing account";; 11 jessica) 12 echo "Do not forget to log off when you're done";; 13 *) 14 echo "Sorry, you are not allowed here";; 15 esac
16 $ 17 $ ./test26.sh
18 Welcome, rich 19 Please enjoy your visit 20 $
case命令提供了一個更清晰的方法來為變量每個可能的值指定不同的選項。
小結
結構化命令允許你改變shell腳本的正常執行流。最基本的結構化命令是if-then語句。該語句允許你執行一個命令並根據該命令的輸出來執行其他命令。
也可以擴展if-then語句,加入一組當指定命令失敗后由bash shell執行的命令。僅在測試命令返回非零退出狀態碼時,if-then-else語句才允許執行命令。
也可以將if-then-else語句通過elif語句連接起來。elif等同於使用else if語句,會在測試命令失敗時提供額外的檢查。
在很多腳本中,你可能希望測試一種條件而不是一個命令,比如數值、字符串內容、文件或目錄的狀態。test命令為你提供了測試這些條件的簡單方法。如果條件為TRUE,test命令會為if-then語句產生退出狀態碼0。如果條件為FALSE,test命令會為if-then語句產生一個非零的退出狀態碼。
方括號是與test命令同義的特殊bash命令。可以在if-then語句中將測試條件放在方括號中來測試數值、字符串和文件條件。
雙括號使用另一種操作符進行高級數學運算。雙方括號命令允許高級字符串模式匹配運算。
最后,本章討論了case命令。該命令是執行多個if-then-else命令的簡便方式,它會參照一個值列表來檢查單個變量的值。