六、Shell指令碼的條件測試
語法1:test <測試表達式> 利用test命令進行條件測試表達式的方法。test命令與<測試表達式>之間至少有一個空格。 語法2:[ <測試表達式> ] 通過[](單中括號)進行條件測試表達式的方法,和test命令用法相同。[]的邊界和內容之間至少有一個空格。 語法3:[[ <測試表達式> ]] 通過[[]](雙中括號)進行條件測試表達式的方法,比test和[]更新的語法格式。[[]]的邊界和內容之間至少有一個空格。 語法4:((<測試表達式>)) 通過(())(雙小括號)進行條件測試表達式的方法,一般用於if語句。(())(雙小括號)兩端不需要有空格。
注意: 1)、語法1中的test命令和語法2中的[]是等價的。語法3中的[[]]為擴充套件的test命令,語法4中的(())常用於計算,:建議使用相對友好的語法2,即中括號([])的語法格式。 2)、在[[]](雙中括號)中可以使用萬用字元等進行模式匹配,這是其區別於其他幾種語法格式的地方。 3)、&&、||、>、<等操作符可以應用於[[]]中,但不能應用於[]中,在[]中一般用-a、-o、-gt(用於整數)、-lt(用於整數)代替上述操作符。 4)、對於整數的關係運算,也可以使用Shell的算術運算子(())
test條件測試的語法格式為:test<測試表達式> 對於如下語句: test -f file && echo true || echo false
該語句表示如果file檔案存在,則輸出true,否則(||)輸出false。這裡的&&是並且的意思。test的-f引數用於測試檔案是否為普通檔案,test命令若執行成功(為真),則執行&&後面的命令,而||後面的命令是test命令執行失敗之後(為假)所執行的命令。 test命令測試表達式的邏輯也可以用上述表達形式的一半邏輯(即僅有一個&&或||)來測試,示例如下。
test -f /tmp/test.txt && echo 1 #<==若表示式成功,則輸出1。 test -f /tmp/test.txt || echo 0 #<==若表示式不成功,則輸出0。
提示:關於test測試表達式的更多知識可執行man test檢視幫助,大部分場景都會使用[]的語法替代test命令的語法。
案例
在test命令中使用-f選項(檔案存在且為普通檔案則表示式成立)測試檔案。
判斷/tmp是否存在一個ywx的檔案,存在則列印true,不存在則列印false [root@node1 ~]# test -f /tmp/ywx && echo true || echo false false #ywx檔案不存在,列印false [root@node1 ~]# touch /tmp/ywx [root@node1 ~]# test -f /tmp/ywx && echo true || echo false true #ywx檔案存在,列印true
判斷king的字元長度是否為0,為0則列印1,不為0則列印0 [root@node1 ~]# test -z "king" && echo 1 || echo 0 0 #king的字串長度不為0,列印結果為0 判斷是否給一個變數SEAL賦值,賦值則列印結果為0,沒有賦值則列印結果為1 [root@node1 ~]# echo $SEAL [root@node1 ~]# test -z "$SEAL" && echo 1|| echo 0 1 #SEAL變數沒有被賦值,結果顯示為1 [root@node1 ~]# SEAL=ywx [root@node1 ~]# echo $SEAL ywx [root@node1 ~]# test -z "$SEAL" && echo 1|| echo 0 0 #SEAL的賦值為ywx,列印結果為0
[]條件測試的語法格式為:[ <測試表達式> ],注意[]兩邊有空格
-f /tmp/ywx.txt ] && echo 1 || echo 0
如果/tmp/ywx.txt檔案存在,則輸出1,否則(||)輸出0。這裡的&&表示並且。[]的應用同test命令,若中括號裡的命令執行成功(返回真),則執行&&後面的命令,否則執行||後面的命令。 []測試表達式的邏輯也可以用如下的語法來判斷邏輯的表示式寫法(test命令的用法也適合於此),即: [ -f /tmp/ywx.txt ] && echo 1 #<==若表示式成功,則輸出1。 [ -f /tmp/ywx.txt ] || echo 0 #<==若表示式不成功,則輸出0
提示:[]命令的選項和test命令的選項是通用的,因此,使用[]時的引數選項可以通過man test命令獲得幫助。
案例
在[]使用-f選項(檔案存在且為普通檔案則表示式成立)測試檔案。
判斷/tmp是否存在一個ywx的檔案,存在則列印true,不存在則列印false [root@node1 ~]# [ -f /tmp/ywx ]&& echo true|| echo false false [root@node1 ~]# touch /tmp/ywx [root@node1 ~]# [ -f /tmp/ywx ]&& echo true|| echo false true
[[]]條件測試的語法格式為:[[ <測試表達式> ]]。注意[[]]兩邊有空格
[[ -f /tmp/ywx.txt ]] && echo 1 || echo 0
如果/tmp/ywx.txt檔案存在就輸出1,否則(||)就輸出0。這裡的&&表示並且。[[]]的應用屬於[]和test命令的擴充套件命令,功能更豐富也更復雜。如果雙中括號裡的表示式成立(為真),則執行&&後面的命令,否則執行||後面的命令。 [[]]測試表達式的邏輯也可以使用如下的部分邏輯形式,即: [[ -f /tmp/ywx.txt ]] && echo 1 #<==若表示式成功則輸出1。 [[ -f /tmp/ywx.txt ]] || echo 0 #<==若表示式不成功則輸出0。
另外,邏輯操作符&&和||的兩端可以有空格也可以無空格。
雙中括號內部的兩端要有空格,[[]]裡的測試判斷選項,也可以通過man test來獲得,[[]]表示式與[]和test用法的選項部分是相同的,其與[]和test測試表達式的區別在於,在[[]]中可以使用萬用字元等進行模式匹配;並且&&、||、>、<等操作符可以應用於[[]]中,但不能應用於[]中,在[]中一般使用-a、-o、-gt(用於整數)、-lt(用於整數)等操作符代替上文提到的用於[[]]中的符號。除了使用萬用字元功能之外,建議放棄這個雙中括號的寫法,雖然它是較新的test命令的語法格式。
案例
在[[]]使用-f選項(檔案存在且為普通檔案則表示式成立)測試檔案。
判斷/tmp是否存在一個ywx的檔案,存在則列印true,不存在則列印false [root@node1 ~]# [[ -f /tmp/ywx ]]&& echo true|| echo false false [root@node1 ~]# touch /tmp/ywx [root@node1 ~]# [[ -f /tmp/ywx ]]&& echo true|| echo false true
-d(directory)目錄 檔案存在且為目錄則位真,及測試表達式成立 -f(file)檔案 檔案存在且為普通檔案則位真,及測試表達式成立 -e(exist) 檔案存在則為真,及測試表達式成立。不區分檔案或目錄。 -r(read)檔案 檔案存在且有可讀許可權則為真,及測試表達式成立 -s(size)檔案 檔案存在且檔案小大不為0則為真,及測試表達式成立 -w(write)檔案 檔案存在且有可寫許可權則為真,及測試表達式成立 -x(executable)檔案 檔案存在且有可執行許可權則為真,及測試表達式成立 -L(link)檔案 檔案存在且為連結檔案則為真,及測試表達式成立 f1 -nt f2, nt(newer than) 檔案f1比檔案f2新則為真,及測試表達式成立。根據檔案的修改時間來計算 f1 -ot f2, ot(older than) 檔案f1比檔案f2舊則為真,及測試表達式成立。根據檔案的修改時間來計算
[root@node1 ~]# [ -f /etc/hosts ]&&echo 1|| echo 0 1 #檔案存在則為1,不存在則為0
[root@node1 ~]# [ -f /etc ]&&echo 1|| echo 0 0 #不存在/etc的普通檔案 [root@node1 ~]# [ -d /etc ]&&echo 1|| echo 0 1 #/etc存在且為目錄 [root@node1 ~]# [ -e /etc ]&&echo 1|| echo 0 1 #/etc存在就行,不管是目錄還是檔案 #/etc目錄存在為1,不存在為0
[root@node1 ~]# ll /etc/hosts -rw-r--r--. 1 root root 158 Jun 7 2013 /etc/hosts [root@node1 ~]# [ -r /etc/hosts ]&& echo 1|| echo 0 1 #有r許可權 [root@node1 ~]# [ -w /etc/hosts ]&& echo 1|| echo 0 1 #有w許可權 [root@node1 ~]# [ -x /etc/hosts ]&& echo 1|| echo 0 0 #無x許可權 [root@node1 ~]# su - ywx Last login: Sun Oct 4 03:32:51 CST 2020 on pts/0 ni hao shell [ywx@node1 ~]$ ll /etc/hosts -rw-r--r--. 1 root root 158 Jun 7 2013 /etc/hosts [ywx@node1 ~]$ [ -r /etc/hosts ]&&echo 1||echo 0 1 [ywx@node1 ~]$ [ -w /etc/hosts ]&&echo 1||echo 0 0 [ywx@node1 ~]$ [ -x /etc/hosts ]&&echo 1||echo 0 0
4、測試檔案大小是否為0
[root@node1 ~]# ll /etc/hosts -rw-r--r--. 1 root root 158 Jun 7 2013 /etc/hosts [root@node1 ~]# ll /tmp/ywx -rw-r--r-- 1 root root 0 Oct 5 22:46 /tmp/ywx [root@node1 ~]# [ -s /etc/hosts ]&&echo 1||echo 0 1 [root@node1 ~]# [ -s /etc/ywx ]&&echo 1||echo 0 0
[root@node1 ~]# file1="/etc" [root@node1 ~]# echo $file1 /etc [root@node1 ~]# [ -f "$file1" ]&&echo 1||echo 0 0 #變數$file1不為檔案 [root@node1 ~]# [ -d "$file1" ]&&echo 1||echo 0 1 #變數$file1是目錄 [root@node1 ~]# [ -s "$file1" ]&&echo 1||echo 0 1 #變數$file1大小不0 [root@node1 ~]# [ -e "$file1" ]&&echo 1||echo 0 1 #變數$file1存在
[root@node1 ~]# unset KAKA [root@node1 ~]# echo $KAKA #變數KAKA沒有賦值 [root@node1 ~]# [ -f $KAKA ]&& echo 1||echo 0 1 [root@node1 ~]# [ -f "$KAKA" ]&& echo 1||echo 0 0 #對變數而言不加"",當該變數沒有賦值時結果不正確的
6、特殊條件測試表達式案例
[ 條件1 ] &&{ 命令1 命令2 命令3 }
上面的判斷相當於下面if語句的效果。
if [ 條件1 ] then
命令1
命令2
命令3
fi
如果/etc存在且為目錄時則同時列印etc is exist和 etc is directory [root@node1 ~]# [ -d /etc ] && { echo "etc is exist";echo "etc is directory"; }||echo "etc not exist" etc is exist etc is directory #注意{}兩邊要有空格,每條命令以";"結尾
1、操作符
字串測試操作符的作用包括:比較兩個字串是否相同、測試字串的長度是否為零、字串是否為NULL等
-n "字串" 若字串長度不為0,則為真,及測試表達式成立,n(no zero) -z "字串" 若字串長度為0,則為真,及測試表達式成立,z(zero) "字串1" = "字串2" 若字串1等於字串2,則為真,及測試表達式成立,也可以使用"==" "字串1" != "字串2" 若字串1不等於字串2,則為真,及測試表達式成立,不能使用!== ·對於字串的測試,一定要將字串加雙引號之後再進行比較。如[ -n "$myvar" ],特別是使用[]的場景。 ·比較符號(例如=和!=)的兩端一定要有空格。 ·“!=”和“=”可用於比較兩個字串是否相同。
[root@node1 ~]# [ -n "abc" ] && echo 1 || echo 0 #<==如果字串長度不為0,則輸出1,否則輸出0。 1 #<==因為字串為abc,長度不為0,因此為真,輸出1。 [root@node1 ~]# test -n "abc" && echo 1 || echo 0 #<==test的用法同上述[]的用法。1 [root@node1 ~]# test -n "" && echo 1 || echo 0 0 [root@node1 ~]# var="ywx1" #<==給變數var賦值ywx1字串。 [root@node1 ~]# [ -n "$var" ] && echo 1 || echo 0 #<==如果字串長度不為0, 則輸出1,否則輸出0。 1 #<==因為變數var內容字串為ywx1,長度不為0,因此為真,輸出1。 [root@node1 ~]# [ -n $var ] && echo 1 || echo 0 #<==去掉雙引號在這裡看起來也是對的,不過還是加上為好。 1 [root@node1 ~]# var="ywx1" [root@node1 ~]# [ -z "$var" ] && echo 1 || echo 0 #<==使用-z,變數長度為0,則為真。 0 #<==變數var的值為ywx1,長度不為0,所以表示式不成立,輸出0。 [root@node1 ~]# [ "abc" = "abc" ] && echo 1 || echo 0 #<==字串相等,輸出1,注意“=”兩端要有空格。 1 [root@node1 ~]# [ "abc" = "abd" ] && echo 1 || echo 0#<==字串不相等,輸出0,注意“=”兩端要有空格。 0 [root@node1 ~]# [ "$var" = "ywx1" ] && echo 1 || echo 0 #<==變數值和字串相等,輸出1。 1 [root@node1 ~]# [ "$var" == "ywx1" ] && echo 1 || echo 0 #<==使用“==”代替“=”,注意“=”兩端要有空格。 1 [root@node1 ~]# [ "$var"!= "ywx1" ] && echo 1 || echo 0 0
進行字串比較時,等號兩端沒有空格帶來的問題
[root@node1 ~]# ["abc"="1"] && echo 1||echo 0 #<==若等號兩端不帶空格,則會出現明顯的邏輯錯誤。 1 #<==明明表示式不成立,卻輸出了1。 [root@node1 ~]# [ "abc" = "1" ] && echo 1||echo 0 #<==帶空格的就是準確的。 0 #<==表示式不成立,輸出0 #字串比較時若等號兩端沒有空格,則會導致判斷出現邏輯錯誤,即使語法沒問題,但是結果依然可能不對。
字串不加引號可能帶來的問題。
[root@node1 ~]# var="" #<==將變數內容置為空。 [root@node1 ~]# [ -n "$var" ] && echo 1 || echo 0 #<==有雙引號。 0 #<==給變數加雙引號,返回0,-n不為空時為真,因為變數內容為空,因此輸出0是對的。 [root@node1 ~]# [ -n $var ] && echo 1 || echo 0 #<==去掉雙引號。 1 #<==同樣的表示式,不加引號和加雙引號後測試的結果相反,可見加雙引號的重要性。 [root@node1 ~]# [ -z "$var" ] && echo 1 || echo 0 #<==如果字串長度為0,則輸出1,否則輸出0。 1 #字串不加雙引號,可能會導致判斷上出現邏輯錯誤,即使語法沒問題,但是結果依然可能不對。
1、整數二元比較操作符
在[]和test中使用的比較符
-eq:相等 -ne: 不等於 -gt: 大於 -ge: 大於等於 -lt: 小於 -le:小於等於
==或=
!=
>
>=
<
<=
1)·“=”和“!=”也可在[]中做比較使用,但在[]中使用包含“>”和“<”的符號時,需要用反斜線轉義,有時不轉義雖然語法不會報錯,但是結果可能會不對。 2)·也可以在[[]]中使用包含“-gt”和“-lt”的符號,但是不建議這樣使用。 3)·比較符號兩端也要有空格。
二元數字在[]中使用“<”、“>”非標準符號的比較。
[root@node1 ~]# [ 2 > 1 ] && echo 1 || echo 0 1 [root@node1 ~]# [ 2 < 1 ] && echo 1 || echo 0 1 #<==這裡的結果邏輯不對,條件不成立,則應該返回0,可見,“<”操作符在[]裡使用時會帶來問題。 [root@node1 ~]# [ 2 \< 1 ] && echo 1 || echo 0 0 #<==轉義後這裡是正確的。 [root@node1 ~]# [ 2 = 1 ] && echo 1 || echo 0 #<==比較相等符號是正確的。 0 [root@node1 ~]# [ 2 = 2 ] && echo 1 || echo 0 #<==比較相等符號是正確的。 1 [root@node1 ~]# [ 2!= 2 ] && echo 1 || echo 0 #<==比較不相等符號也是正確的。 0
[root@node1 ~]# [ 2 -gt 1 ] && echo 1 || echo 0 1 #<==2大於1成立,輸出1。 [root@node1 ~]# [ 2 -ge 1 ] && echo 1 || echo 0 1 #<==2大於等於1成立,輸出1。 [root@node1 ~]# [ 2 -le 1 ] && echo 1 || echo 0 0 #<==2小於等於1不成立,輸出0。 [root@node1 ~]# [ 2 -lt 1 ] && echo 1 || echo 0 0 #<==2小於1不成立,輸出0。
[root@node1 ~]# [[ 5 > 6 ]] && echo 1 || echo 0 0 #<==5大於6不成立,輸出0。 [root@node1 ~]# [[ 5 < 6 ]] && echo 1 || echo 0 1 #<==5小於6成立,輸出1。 [root@node1 ~]# [[ 5!= 6 ]] && echo 1 || echo 0 1 #<==5不等於6成立,輸出1。 [root@node1 ~]# [[ 5 = 6 ]] && echo 1 || echo 0 0 #<==5等於6不成立,輸出0。 [root@node1 ~]# [[ 5 -gt 6 ]] && echo 1 || echo 0 0 #<==5大於6不成立,輸出0。 [root@node1 ~]# [[ 5 -lt 6 ]] && echo 1 || echo 0 1 #<==5小於6成立,輸出1。 [root@node1 ~]# [[ 65 > 66 ]] && echo 1 || echo 0 0 #<==65大於66不成立,輸出0。 [root@node1 ~]# [[ 65 < 66 ]] && echo 1 || echo 0 1 #<==65小於66成立,輸出1。 [root@node1 ~]# [[ 65 = 66 ]] && echo 1 || echo 0 0 #<==65等於66不成立,輸出0。
[root@node1 ~]# ((3>2)) && echo 1 || echo 0 1 #<==3大於2成立,輸出1。 [root@node1 ~]# ((3<2)) && echo 1 || echo 0 0 #<==3小於2不成立,輸出0。 [root@node1 ~]# ((3==2)) && echo 1 || echo 0 0 #<==3等於2不成立,輸出0。 [root@node1 ~]# ((3!==2)) && echo 1 || echo 0 #<==“!==”符號不可用,語法錯誤 bash:((:3!==2:syntax error:operand expected (error token is "=2") 0 [root@node1 ~]# ((3!=2))&& echo 1 || echo 0 1
1)·整數加雙引號的比較是對的。 2)·[[]]中用類似-eq等的寫法是對的,[[]]中用類似>、<的寫法也可能不對,有可能會只比較第一位,邏輯結果不對。 3)·[]中用類似>、<的寫法在語法上雖然可能沒錯,但邏輯結果不對,可以使用=、!=正確比較。 4)·(())中不能使用類似-eq等的寫法,可以使用類似>、<的寫法。
整數變數測試實踐示例
[root@node1 ~]# a1=98;a2=99 [root@node1 ~]# [ $a1 -eq $a2 ] && echo 1 || echo 0 #<==測試$a1是否等於$a2 0 [root@node1 ~]# [ $a1 -gt $a2 ] && echo 1 || echo 0 #<==測試$a1是否大於$a2。 0 [root@node1 ~]# [ $a1 -lt $a2 ] && echo 1 || echo 0 #<==測試$a1是否小於$a2。 1
[root@node1 ~]# [[ $a1 > $a2 ]] && echo 1 || echo 0 #<==測試$a1是否大於$a2,儘量不用此寫法。 0 [root@node1 ~]# [[ $a1 < $a2 ]] && echo 1 || echo 0 #<==測試$a1是否小於$a2,儘量不用此寫法。 1 [root@node1 ~]# (( $a1 >= $a2 )) && echo 1 || echo 0 #<==測試$a1是否大於等於$a2,此寫法也可以。 0 [root@node1 ~]# (( $a1 <= $a2 )) && echo 1 || echo 0 #<==測試$a1是否小於等於$a2, 1
[ num1 –eq num2 ] #<==注意比較符號兩邊的空格和比較符號的寫法,必須要有空格。
(( num1 > num2 )) #<==比較符號兩邊無需空格(多空格也可),使用常規數學的比較符號即可。
五、邏輯操作符
1、邏輯操作符
在[]和test中使用
-a and,與,兩端都為真,則結果為真 -o or,或,兩端有一個為真,則結果為真 ! not,非,兩端取反,則結果為真
在[[]]和(())中使用
&& and,與,兩端都為真,則結果為真 || or,或,兩端有一個為真,則結果為真 ! not,非,兩端取反,則結果為真
1)·邏輯操作符前後的表示式是否成立,一般用真假來表示。 2)·“!”的中文意思是反,即與一個邏輯值相反的邏輯值。 3)·-a的中文意思是“與”(and或&&),前後兩個邏輯值都為“真”,綜合返回值才為“真”,反之為“假”。 4)·-o的中文意思是“或”(or或||),前後兩個邏輯值只要有一個為“真”,返回值就為“真”。 5)·連線兩含[]、test或[[]]的表示式可用&&或||。
2、邏輯操作符運算規則
-a和&&的運算規則:只有邏輯操作符兩端的表示式都成立時才為真;真(true)表示成立,對應的數字為1;假(false)表示不成立,對應的數字為0
[root@node1 ~]# [ -f /etc/hosts -a -f /etc/services ] && echo 1 || echo 0 #<==單中括號檔案測試。 1 [root@node1 ~]# [[ -f /etc/hosts && -f /etc/services ]] && echo 1 || echo 0 #<==雙中括號檔案測試。 1
使用-a和&&的綜合表示式結果,相當於將兩端表示式結果的對應數字(0或1)相乘。 當左邊為真,右邊為假的時候,相乘結果為1*0=0,總結果為假(0)。 當左邊為假,右邊為真的時候,相乘結果為0*1=0,總結果依然為假(0)。 當左邊為真,右邊也為真的時候,相乘結果為1*1=1,總結果為真(1)。 當左邊為假,右邊也為假的時候,相乘結果為0*0=0,總結果為假(0)。 簡單表示為: and結果1*0=0 假 and結果0*1=0 假 and結果1*1=1 真 and結果0*0=0 假 結論:and(&&)也稱為與,只有兩端都是1時才為真,相當於取前後表示式的交集。
-o或||兩端都是0才為假,任何一端不為0就是真,這相當於將兩邊表示式結果的對應數字(0或1)相加,對應的表示式為:
[root@node1 ~]# [ 5 -eq 6 -o 5 -gt 3 ] && echo 1 || echo 0 1 [root@node1 ~]# ((5==6||5>3)) && echo 1 || echo 0 1
-o或||的運算規則為: 當左邊為真,右邊為假的時候,相加結果為1+0=1,總結果為真(1)。 當左邊為假,右邊為真的時候,相加結果為0+1=1,總結果依然為真(1)。 當左邊為真,右邊也為真的時候,相加結果為1+1=2,總結果為真(1),非0即真。 當左邊為假,右邊也為假的時候,相加結果為0+0=0,總結果為假(0)。 簡單表示為: or 結果1+0=1 真 or 結果1+1=2 真(非0即為真) or 結果0+1=1 真 or 結果0+0=0 假 結論:or(||)也稱為或,它的兩端表示式的結果都是0時才為假,不為0就是真。相當於對前後表示式結果取並集。
案例
[]裡的邏輯操作符配合檔案測試表達式使用的示例。
[root@node1 ~]# f1=/etc/rc.local;f2=/etc/services #<==定義f1和f2兩個變數,分別賦值兩個已知存在的檔案路徑。 [root@node1 ~]# echo -ne "$f1 $f2\n" #<==測試輸出f1和f2兩個變數的值。 /etc/rc.local /etc/services [root@node1 ~]# [ -f "$f1" -a -f "$f2" ] && echo 1 || echo 0 #<==[]裡使用-a(and)。 #<==測試f1和f2兩個變數值是否都為普通檔案,如果成立,則輸出1,否則輸出0。 1 [root@node1 ~]# [ -f "$f1" -o -f "$f222" ] && echo 1 || echo 0 #<==測試f1和f222兩個變數值是否都為普通檔案,如果成立,則輸出1,否則輸出0;f222變數是未定義的,但是f1變數是有的,並且是普通檔案,-o兩邊有一個表示式成立(即為真),因此輸出1。 1 [root@node1 ~]# [ -f "$f111" -o -f "$f222" ] && echo 1 || echo 0 #<==測試f111和f222兩個變數值中是否有一個為普通檔案,如果成立,則輸出1,否則輸出0。 0 #<==f111和f222兩個變數都是未定義的,因此輸出0。 [root@node1 ~]# [ -f "$f1" && -f "$f2" ] && echo 1 || echo 0 #<==這是錯誤語法,[]中不能用&&或||。 -bash:[:missing `]' 0 [root@node1 ~]# [ -f "$f1" ] && [ -f "$f2" ] && echo 1 || echo 0 #<==如果在[]中想使用&&,則這樣用。 1
[root@node1 ~]# a="ywx";b="kaka" #<==定義a和b兩個變數,賦值兩個已知的字串。 [root@node1 ~]# echo -ne "$a $b\n" #<==測試輸出a和b兩個變數的值。 ywx kaka [root@node1 ~]# [[!-n "$a" && "$a" = "$b" ]] && echo 1 || echo 0 #<== [[]]內部用&&或||。 #<==測試$a長度不為0是否成立,並且$a等於$b是否成立,兩個表示式是否同時成立。 0 #<==因為$a長度不為0成立,結果為1,加上前面“!”取反,就是不成立,結果變為0。$a等於$b成立,結果為1,兩個表示式綜合起來0*1=0,因此不成立,輸出0。 [root@node1 ~]# [[ -z "$a" || "$a"!= "$b" ]] && echo 1 || echo 0 #<== [[]]中||的使用。 1 [root@node1 ~]# [[ -z "$a" -o "$a"!= "$b" ]] && echo 1 || echo 0 #<== [[]]內部用-a或-o會報錯。 -bash:syntax error in conditional expression -bash:syntax error near `-o'
[root@node1 ~]# m=21;n=38 [root@node1 ~]# ((m>20&&n>30)) && echo 1 || echo 0 #<== (())內部用&&或||。 1 [root@node1 ~]# ((m<20||n>30)) && echo 1 || echo 0 1 [root@node1 ~]# ((m<20||n<30)) && echo 1 || echo 0 0 [root@node1 ~]# ((m<20 -a n<30)) && echo 1 || echo 0 #<== (())內部用-a或-o也會報語法錯誤。 -bash:((:m<20 -a n<30:syntax error in expression (error token is "n<30") 0
[root@node1 ~]# m=21;n=38 [root@node1 ~]# [ $m -gt 20 -a $n -lt 30 ] && echo 1 || echo 0 0 [root@node1 ~]# [ $m -gt 20 ]||[ $n -lt 30 ] && echo 1 || echo 0 #<==多個[]號之間用&&或||連線。 1
1)·“-a”和“-o”邏輯操作符號需要用於[]中。 2)·“&&”和“||”邏輯操作符號可用於[[]]或(())中,也可以在外部連線多個[]。 3)·注意,在[]和[[]]的兩端及比較符號的兩端,必須要有空格,但是對於(())不需要。
輸入或通過命令列傳入一個字元或數字,如果傳入的數字等於1,就列印1;如果等於2,就列印2;如果不等於1也不能於2,就提示輸入不對,然後退出程式。
參考答案1:使用read讀入內容方案。
#!/bin/sh echo -n "pls input a char:" #<==列印提示字串,-n表示不換行。 read var #<==讀取使用者的輸入並賦值給var變數。 [ "$var" == "1" ] &&{ #<==條件表示式判斷,看變數是否等於1,注意普通字元比較多地用字串比較的語法,即加雙引號比較,而不是使用整數比較的語法,整數比較容易出錯,除非確定是整數。 echo 1 exit 0 #<==每個邏輯正確,則以返回值0退出指令碼,從而避免執行指令碼後面無用的程式碼。 } [ "$var" == "2" ] &&{ #<==條件表示式判斷,看變數是否等於2。 echo 2 exit 0 } [ "$var"!= "2" -a "$var"!= "1" ] &&{ #<==條件表示式加邏輯操作符判斷,看變數是否不等於2,並且不等於1,如果都成立,則執行命令。 echo error exit 0 }
參考答案2:使用指令碼命令列傳參讀入內容的解決方案。
#!/bin/sh var=$1 #<==將上文的read讀入資訊,改為指令碼傳參,接收指令碼的第一個引數$1賦值給var。 [ "$var" == "1" ] &&{ echo 1 exit 0 } [ "$var" == "2" ] &&{ echo 2 exit 0 } [ "$var"!= "2" -a "$var"!= "1" ] &&{ echo error exit 0 }
開發Shell指令碼,分別實現以指令碼傳參和read讀入的方式比較兩個整數的大小。用條件表示式(禁止用if)進行判斷並以螢幕輸出的方式提醒使用者比較的結果。注意:一共是開發兩個指令碼。在用指令碼傳參和read讀入的方式實現時,需要對變數是否為數字及傳參個數是否正確給予提示。
參考答案1:採用read方法。
#!/bin/sh read -p "Pls input two num:" a b #<==請求使用者輸入兩個引數,讀入後分別賦值給變數a和b。 #no1 [ -z "$a" ]||[ -z "$b" ] &&{ #<==如果$a變數長度為0或$b變數長度為0,即任何一個 變數為空,則執行命令。 echo "Pls input two num again." #<==a或b沒值,表示使用者輸入錯誤,給出提示。 exit 1 #<==以返回值1退出指令碼。 } #no2 expr $a + 10 &>/dev/null #<==判斷$a是否為整數,不輸出任何資訊。前文已講解過了expr 判斷整數的方式。 RETVAL1=$? #<==將返回值賦值給RETVAL1,後面會用這個返回值做判斷。 expr $b + 10 &>/dev/null #<==判斷$b是否為整數,不輸出任何資訊。 RETVAL2=$? #<==將返回值賦值給RETVAL2,後面會用這個返回值做判斷。 test $RETVAL1 -eq 0 -a $RETVAL2 -eq 0||{ #<==利用test進行返回值是否為0的判斷。如果有一個返回值不為0,則說明有一個變數不為整數,不合要求,列印提示後退出。 echo "Pls input two "num" again." exit 2 } #no3 [ $a -lt $b ] &&{ #<==整數比較,$a是否小於$b。 echo "$a < $b" exit 0 } #no4 [ $a -eq $b ] &&{ #<==整數比較,$a是否等於$b。 echo "$a = $b" exit 0 } #no5 [ $a -gt $b ] &&{ #<==整數比較,$a是否大於$b。 echo "$a > $b" }
參考答案2:通過命令列傳參的方法實現。
#!/bin/sh a=$1 #<==將上文的read讀入資訊改為指令碼傳參,接收指令碼的第一個引數$1賦值給a。 b=$2 #<==將上文的read讀入資訊改為指令碼傳參,接收指令碼的第二個引數$2賦值給b。 #no1 [ $# -ne 2 ] &&{ #<==傳參專用判斷手法,判斷傳參個數是否為兩個。 echo "USAGE:$0 NUM1 NUM2" #<==傳參不合要求,給出用法提示。 exit 1 #<==以返回值1退出指令碼。 } #no2 expr $a + 10 &>/dev/null #<==整數判斷,前文已講。 RETVAL1=$? expr $b + 10 &>/dev/null #<==整數判斷,前文已講。 RETVAL2=$? test $RETVAL1 -eq 0 -a $RETVAL2 -eq 0||{ echo "Pls input two "num" again." exit 2 } #no3 [ $a -lt $b ] &&{ echo "$a < $b" exit 0 } #no4 [ $a -eq $b ] &&{ echo "$a = $b" exit 0 } #no5 [ $a -gt $b ] &&{ echo "$a > $b" }