Shell筆記3——腳本的條件測試與比較

本文檔主要講解Shell變量的數值計算與實踐shell

基本大綱:express

  • 1.Shell腳本的條件測試編程

  • 2.文件測試表達式bash

  • 3.字符串測試表達式less

  • 4.整數二元比較操做符ide

  • 5.邏輯操做符測試

  • 6.測試表達式test、[]、[[]]、(())的區別總結spa




一:shell腳本的條件測試token

 1)條件測試方法綜述 ip

  一般,在bash的各類條件結構和流程控制結構中都要進行各類測試,而後根據測試結構執行不一樣的操做,有時也會與if等條件語句相結合,來完成測試判斷,以減小程序運行的錯誤。

執行條件測試表達式後一般會返回"真"或"假",就像執行命令後返回的值爲0表示真,非0表示假同樣。

Bash編程中條件測試經常使用的語法:

     

  條件測試語法

                                       

                                 說明


語法一:test<測試表達式>


這是利用test命令進行測試表達式的方法。test命令和"<測試表達式>"之間至少有一個空格;


語法二:[<測試表達式>]


這是經過[](單中括號)進行條件測試表達式的方法,和test命令的用法相同。[]的邊界和內容之間至少有一個空格;


語法三:[[<測試表達式>]]


這是經過[[]](雙中括號)進行條件測試表達式的方法。是比test和[]更新的語法格式。[[]]的邊界和內容之間至少有一個空格;


語法四:((<測試表達式>))


這是經過(())(雙小括號)進行條件測試表達式的方法,通常用於if語句裏。(())(雙小括號)兩端不須要有空格;通常都少用到

針對上表格有幾個注意事項須要說明下:

  • 語法一中的test命令和語法二中的[]是等價的。語法三種的[[]]爲擴展的test命令,語法四中的(())經常使用語計算,建議使用相對友好的語法二,即中括號[]的語法格式。

  • 在[[]]中可使用通配符等進行模式匹配,這是區別於其餘幾種語法格式的地方。

  • &&、||、>、<\等操做符能夠應用於[[]]中,但不能應用於[]中,在[]中通常用-a、-o、-gt(用於整數)、-lt(用於整數)代替上述操做符。

  • 對於整數的關係運算,也可使用shell的算數運算符(())。

2)語法一:test條件測試的語法及示例

test <測試表達式>
test -f file && echo true || echo false 
#該語句表示若是file存在,則輸出true,不然(||)輸出false。這裏的&&是而且的意思。test的-f參數用於測試文件是否爲普通文件,test命令若執行成功(爲真),則執行&&後面的命令,
若是執行失敗,則執行||後面的命令

範例1:在test命令中使用-f選項測試文件是否存在
[root@aliyun tj]# test -f file && echo true || echo false 
false
[root@aliyun tj]# touch file
[root@aliyun tj]# test -f file && echo true || echo false 
true

範例2:在test命令中使用-z選項測試字符串長度,爲0則表達式成立
[root@aliyun tj]# test -z "ywxi" && echo 1 || echo 0        #字符串長度不爲0,因此表達式爲假,返回結果爲0
0
[root@aliyun tj]# char="ywxi"
[root@aliyun tj]# test -z "$char" && echo 1 || echo 0
0
[root@aliyun tj]# char=""    
[root@aliyun tj]# test -z "$char" && echo 1 || echo 0
1


3)語法二:中括號[]條件測試語法及示例

[]條件測試的語法格式爲[<測試表達式>]
[ -f file ] && echo true || echo false
#注意:中括號內部的兩端要有空格,[]和test等價,即test的全部判斷選項均可以直接[]裏使用。

範例1:利用[]加-f選項(文件存在且爲普通文件則表達式成立)測試文件。
[root@aliyun tj]# [ -f /tmp/file.txt ] && echo true || echo false        #文件不存在,因此輸出false
false
[root@aliyun tj]# touch /tmp/file.txt
[root@aliyun tj]# [ -f /tmp/file.txt ] && echo true || echo false        #文件存在,全部輸出true
true
[root@aliyun tj]# [ -f /tmp/file.txt ] && echo true 
true
[root@aliyun tj]# [ -f /tmp/file.txt ] || echo false
[root@aliyun tj]# [ -f /tmp/file ] || echo false             #文件不存在,因此不成立,因此執行||後面的輸出
false


4)語法三:[[]]條件測試語法及示例

[[]]條件測試的語法格式爲:[[<測試表達式>]]
#注意:雙中括號裏的兩端也要有空格。
#[[]]和[]與test的主要區別在於,在[[]]中可使用通配符等進行模式匹配;而且&&、||、>、<等操做符能夠應用在[[]]中,但不能應用在[]中,在[]中通常使用-a、-o、-gt等來代替
範例1:
[root@aliyun tj]# [[ -f /tmp/file.txt ]] && echo true || echo false 
true
[root@aliyun tj]# [[ -f /tmp/test.txt ]] && echo true || echo false     
false
[root@aliyun tj]# touch /tmp/test.txt
[root@aliyun tj]# [[ -f /tmp/test.txt ]] && echo true || echo false 
true
[root@aliyun tj]# rm -rf /tmp/test.txt 
[root@aliyun tj]# [[ -f /tmp/test.txt ]] && echo true || echo false
false




二:文件測試表達式

1)文件測試表達式的用法以下表;


 

  經常使用文件測試操做符

                                       

                                說明


-d文件,d的全拼爲directory


  文件存在且爲目錄則爲真,即測試表達式成立;


-f文件,f的全拼爲file


  文件存在且爲普通文件則爲真,即測試表達式成立;


-e文件,e的全拼爲exist


  文件存在則爲真,即測試表達式成立。區別於"-f","-e"不能辨別是目錄仍是文件;


-r文件,r的全拼爲read


  文件存在且可讀測試爲真,即測試表達式成立;


-s文件,s的全拼爲size


  文件存在且文件大小不爲0則爲真,即測試表達式成立;


-w文件,w的全拼爲write


  文件存在則可寫爲真,即測試表達式成立;


-x文件,x的全拼爲executable


  文件存在且可執行爲真,即測試表達式成立;


-L文件,L的全拼爲link


  文件存在且連接文件則爲真,即測試表達式成立;


f1 -nt f2,nt的全拼爲newer than


  文件f1比文件f2新則爲真,即測試表達式成立。根據文件的修改時間來計算;


f1 -ot f2,nt的全拼爲older than


  文件f1比文件f2舊則爲真,即測試表達式成立。根據文件的修改時間來計算;



2)普通文件和目錄測試表達式示例:

[root@aliyun tj]# touch ywxi.txt
[root@aliyun tj]# ls -l ywxi.txt 
-rw-r--r-- 1 root root 0 May 31 13:59 ywxi.txt
[root@aliyun tj]# [ -f ywxi.txt ] && echo 1 || echo 0        #文件存在,表達式成立,輸出爲1
1
[root@aliyun tj]# mkdir ywxi
[root@aliyun tj]# ls -ld ywxi
drwxr-xr-x 2 root root 4096 May 31 14:02 ywxi
[root@aliyun tj]# [ -f ywxi ] && echo 1 || echo 0        #-f判斷文件,ywxi是目錄名,全部表達式不成立,則輸出爲0
0
[root@aliyun tj]# [ -d ywxi ] && echo 1 || echo 0 
1
[root@aliyun tj]# [ -d ywxi.txt ] && echo 1 || echo 0
0
[root@aliyun tj]# [ -e ywxi ] && echo 1 || echo 0         #不區別目錄和文件,存在即爲表達式成立,輸出爲1
1
[root@aliyun tj]# [ -e ywxi.txt ] && echo 1 || echo 0
1


3)文件屬性測試示例:

[root@aliyun tj]# ls -l ywxi.txt 
-rw-r--r-- 1 root root 0 May 31 13:59 ywxi.txt
[root@aliyun tj]# [ -r ywxi.txt ] && echo 1 || echo 0
1
[root@aliyun tj]# [ -w ywxi.txt ] && echo 1 || echo 0 
1
[root@aliyun tj]# [ -x ywxi.txt ] && echo 1 || echo 0 
0
[root@aliyun tj]# chmod 001 ywxi.txt 
[root@aliyun tj]# ls -l ywxi.txt 
---------x 1 root root 0 May 31 13:59 ywxi.txt
[root@aliyun tj]# [ -w ywxi.txt ] && echo 1 || echo 0        #用戶權限位沒w,輸出1是由於root用戶確實能夠寫。這是root用戶特殊的地方
1
[root@aliyun tj]# echo 'echo test' >ywxi.txt 
[root@aliyun tj]# [ -r ywxi.txt ] && echo 1 || echo 0        #用戶權限位沒r,輸出1是由於root用戶確實能夠讀 。這是root用戶特殊的地方
1
[root@aliyun tj]# cat ywxi.txt 
test
[root@aliyun tj]# [ -x ywxi.txt ] && echo 1 || echo 0        
1
[root@aliyun tj]# ./ywxi.txt
test
注意:測試文件的讀、寫、執行等屬性,不光是根據文件屬性rwx的標識來判斷,還要看當前執行測試的用戶是否真的能夠按照對應的權限操做該文件。


4)測試Shell變量示例

[root@aliyun tj]# ls -la
drwxr-xr-x 2 root root 4096 May 31 14:02 ywxi        #目錄
---------x 1 root root   10 May 31 16:41 ywxi.txt    #文件
[root@aliyun tj]# file1=/scripts/practice/tj/ywxi ; file2=/scripts/practice/tj/ywxi.txt
[root@aliyun tj]# echo $file1 $file2
/scripts/practice/tj/ywxi /scripts/practice/tj/ywxi.txt

#對目錄測試
[root@aliyun tj]# [ -f "$file1" ] && echo 1 || echo 0    #不是文件,因此爲假
0
[root@aliyun tj]# [ -d "$file1" ] && echo 1 || echo 0    #是目錄,因此爲真
1
[root@aliyun tj]# [ -s "$file1" ] && echo 1 || echo 0    #目錄存在且大小不爲0,因此爲真
1
[root@aliyun tj]# [ -e "$file1" ] && echo 1 || echo 0    #目錄存在即爲真
1

#對文件測試
[root@aliyun tj]# [ -f "$file2" ] && echo 1 || echo 0    #是文件,因此爲真
1
[root@aliyun tj]# [ -d "$file2" ] && echo 1 || echo 0    #不是目錄,因此爲假
0
[root@aliyun tj]# [ -e "$file2" ] && echo 1 || echo 0    #文件存在,因此爲真
1
[root@aliyun tj]# [ -s "$file2" ] && echo 1 || echo 0    #文件存在且大小不爲0,因此爲真
1

#測試變量的特殊寫法及問題
[root@aliyun tj]# echo $ywxi        #變量爲空

[root@aliyun tj]# [ -f $ywxi ] && echo 1 || echo 0    #變量不存在,但還返回1,邏輯就不對了
1
[root@aliyun tj]# [ -f "$ywxi" ] && echo 1 || echo 0    #變量加上雙引號,邏輯就對了
0

#對於文件實在路徑,雙引號加與不加就沒區別了
[root@aliyun tj]# [ -f /etc/services ] && echo 1 || echo 0
1
[root@aliyun tj]# [ -f "/etc/services" ] && echo 1 || echo 0
1

#在生產環境中,系統NFS啓動腳本的條件測試
[root@localhost practice]# grep '&&' /etc/init.d/nfs|head -2
[ -f /etc/sysconfig/network ] &&  . /etc/sysconfig/network        #若是/etc/sysconfig/network文件存在,則加載文件,不用加雙引
[ -f /etc/sysconfig/nfs ] && . /etc/sysconfig/nfs             #若是/etc/sysconfig/nfs文件存在,則加載文件,不用加雙引




三:字符串測試表達式

1)字符測試表達式

字符串測試操做符的做用包括;比較兩個字符串是否相同、測試字符串的長度是否爲零,字符串是否爲NULL等;


經常使用字符串測試操做符


                                       說明

 

        -n"字符串"

  若字符串的長度不爲0,則爲真,即測試表達式成立,n能夠理解爲no zero;


         -z"字符串"

  若字符串的長度爲0,則爲真,即測試表達式成立,z能夠理解爲zero的縮寫;


       "串1"= "串2"

  若字符串1等於字符串2,則爲真,即測試表達式成立,能夠用"=="代替"=";


      "串1"!="串2"

  若字符串1不等於字符串2,則爲真,即測試表達式成立,但不能用"!=="代替"!=";

如下是針對字符串測試操做符的提示:

  • 對於字符串的測試,必定要將字符串加雙引號以後在進行比較。如[-n $myvar],特別是使用[]的場景;

  • 比較符號(例如=和!=)的兩端必定要有空格;

  • "!="和"="可用於比較兩個字符串是否相同;


2)字符串條件表達式測試實踐:

[root@localhost practice]# [ -n "a" ] && echo 1 || echo 0    #長度不爲0,因此爲真
1
[root@localhost practice]# test -n "a"  && echo 1 || echo 0    
1
[root@localhost practice]# test -n ""  && echo 1 || echo 0     #長度爲0,因此爲假
0
[root@localhost practice]# [ -n "" ] && echo 1 || echo 0   
0
[root@localhost practice]# a=ywxi
[root@localhost practice]# echo $a
ywxi
[root@localhost practice]# [ -n "$a" ] && echo 1 || echo 0    #長度不爲0,因此爲真
1
[root@localhost practice]# [ -n $a ] && echo 1 || echo 0  
1
[root@localhost practice]# [ -z $a ] && echo 1 || echo 0 
0
[root@localhost practice]# [ -z "$a" ] && echo 1 || echo 0
0
[root@localhost practice]# [ "abc" = "abd" ] && echo 1 || echo 0    #字符串不一致,因此爲假
0
[root@localhost practice]# [ "abc" = "abc" ] && echo 1 || echo 0 
1
[root@localhost practice]# [ "$a" = "ywxi" ] && echo 1 || echo 0    #解析了變量的值與ywxi一致     
1
[root@localhost practice]# [ $a = "ywxi" ] && echo 1 || echo 0        #解析了變量的值與ywxi一致  
1
[root@localhost practice]# [ '$a' = "ywxi" ] && echo 1 || echo 0                    #原樣輸出,沒解析了變量的值,不與ywxi一致,因此爲假
0
[root@localhost practice]# [ "$a" != "ywxi" ] && echo 1 || echo 0                   #解析了$a的值與ywxi一致,是相等的。不等於不成立,因此爲假
0


3)字符串測試生產案例:

[root@aliyun tj]# sed -n '30,31p' /etc/init.d/network         #這是系統網卡啓動腳本
# Check that networking is up.
[ "${NETWORKING}" = "no" ] && exit 6    #字符串變量和字符串都加了雙引號,比較符號"="兩端也都有空格




四:整數二元比較操做符 

1)整數二元比較操做符介紹


在[]以及test中使用的比較符號


在(())和[[]]中使用的比較符號


                說明


               -eq


              ==或=


     相等,全拼爲equal


               -ne


                !=


  不相等,全拼爲not equal


               -gt

             

                >


  大於,全拼爲gerater than

          

               -ge


               >=

 大於等於,全拼爲gerater equal


               -lt


               <

  

  小於,全拼爲less than


              -le


              <=


小於等於,全拼爲less equal

如下是針對上述符號的特別說明:

  • "="和"!="也能夠在[]中做比較使用,但在[]中使用包含">"和"<"的符號時,須要用反斜線轉義,有時不轉義雖然語法不會報錯,可是結果可能會不對;

  • 也能夠在[[]]中使用包含"-gt"和"-lt"的符號,可是不建議這樣使用;

  • 比較符號兩端也要有空格;


2)二元數字在[]中使用"<"和">"非標準符號的比較

[root@aliyun tj]# [ 2 > 1 ] && echo 1 || echo 0
1
[root@aliyun tj]# [ 2 < 1 ] && echo 1 || echo 0     #2<1的結果1邏輯是不對的,應該返回0纔是正常的
1
[root@aliyun tj]# [ 2 \< 1 ] && echo 1 || echo 0    #用\轉義後結果邏輯就正常了
0
[root@aliyun tj]# [ 2 = 1 ] && echo 1 || echo 0   
0
[root@aliyun tj]# [ 2 = 2 ] && echo 1 || echo 0 
1
[root@aliyun tj]# [ 2 != 2 ] && echo 1 || echo 0
0


3)二元數字在[]中使用-gt、-le類符號的比較

[root@aliyun tj]# [ 2 -gt 1 ] && echo 1 || echo 0    
1
[root@aliyun tj]# [ 2 -ge 1 ] && echo 1 || echo 0 
1
[root@aliyun tj]# [ 2 -le 1 ] && echo 1 || echo 0 
0
[root@aliyun tj]# [ 2 -lt 1 ] && echo 1 || echo 0 
0

 

4)二元數字配合不一樣種類的操做符在[[]]中的比較

[root@aliyun tj]# [[ 1 > 2 ]] && echo 1 || echo 0    
0
[root@aliyun tj]# [[ 1 < 2 ]] && echo 1 || echo 0 
1
[root@aliyun tj]# [[ 1 = 2 ]] && echo 1 || echo 0 
0
[root@aliyun tj]# [[ 1 != 2 ]] && echo 1 || echo 0
1
[root@aliyun tj]# [[ 1 -gt 2 ]] && echo 1 || echo 0    
0
[root@aliyun tj]# [[ 1 -lt 2 ]] && echo 1 || echo 0 
1
[root@aliyun tj]# [[ 1 -ne 2 ]] && echo 1 || echo 0  
1
[root@aliyun tj]# [[ 1 -eq 2 ]] && echo 1 || echo 0  
0


5)二元數字在(( ))中的比較

[root@aliyun tj]# ((2>1)) && echo 1 || echo 0
1
[root@aliyun tj]# ((2<1)) && echo 1 || echo 0 
0
[root@aliyun tj]# ((2==1)) && echo 1 || echo 0 
0
[root@aliyun tj]# ((2!==1)) && echo 1 || echo 0
-bash: ((: 2!==1: syntax error: operand expected (error token is "=1")        #"!=="符號不可用,語法錯誤
0
[root@aliyun tj]# ((2!=1)) && echo 1 || echo 0 
1


有關[]、[[]]、(())用法的小結:

  • 證書加雙引號的比較是對的

  • [[]]中用相似-eq等的寫法是對的,[[]]中用相似>、<的寫法也可能不對,有可能會只比較第一位,邏輯結果不對

  • []中用相似>、<的寫法在語法上雖然可能沒錯,但邏輯結果不對,可使用=、!=正確比較

  • (())中不能用相似-eq等的寫法,可使用相似>、<的寫法




五:邏輯操做符

1)邏輯操做符介紹

在[]和test中使用的操做符


在[[]]和(())中使用的操做符


                說明


           -a


               &&

and,與,兩端都爲真,則結果爲真


           -o


                ||

or,或,兩端有一個爲真,則結果爲真


            !


                 !

Not,非,兩端相反,則結果爲真

對於上述操做符,有以下提示:

  • 邏輯操做符先後的表達式是否成立,通常用真假來表示;

  • "!"的中文意思是反,即與一個邏輯值相反的邏輯值;

  • -a的中文意思是"與"(and或&&),先後兩個邏輯值都爲"真",綜合返回值才爲"真",反之爲"假";

  • -o的中文意思是"或"(or或||),先後2個邏輯值只要有一個爲"真",返回值就爲"真";

  • 鏈接兩含[]、test或[[]]的表達式可用&&或||;


2)邏輯操做符實踐示例:

1.[]裏的邏輯操做符配合文件測試表達式使用的示例

[root@aliyun tj]# f1=/etc/rc.local ;f2=/etc/services 
[root@aliyun tj]# echo $f1 $f2
/etc/rc.local /etc/services
[root@aliyun tj]# [ -f "$f1" -a -f "$f2" ] && echo 1 || echo 0         #測試f1和f2兩個變量是否都爲文件,成立則輸出1
1
[root@aliyun tj]# [ -f "$f1" -o -f "$f2" ] && echo 1 || echo 0         #測試f1和f2兩個變量有一個是否爲文件,成立則輸出1
1
[root@aliyun tj]# [ -f "$f1" && -f "$f2" ] && echo 1 || echo 0         #&&這是錯誤語法的提示
-bash: [: missing `]'
0
[root@aliyun tj]# [ -f "$f1" ] && [ -f "$f2" ] && echo 1 || echo 0     #正確運用寫法
1


2.[[]]裏的邏輯操做符配合字符串的條件表達式使用的示例

[root@aliyun tj]# a="abc";b="def"
[root@aliyun tj]# echo -ne "$a $b\n"
abc def
[root@aliyun tj]# [[ ! -n "$a" && "$a" = "$b" ]] && echo 1 || echo 0     #$a長度不爲0而且$a等於$b是否成立,必須兩個表達式同時成立 
0
[root@aliyun tj]# [[ -z "$a" -o "$a" != "$b" ]] && echo 1 || echo 0      #內部用-a或-o會報錯
-bash: syntax error in conditional expression
-bash: syntax error near `-o'
[root@aliyun tj]# [[ -z "$a" || "$a" != "$b" ]] && echo 1 || echo 0      
1


3.(())邏輯操做符配合整數的條件表達式測試示例

[root@aliyun tj]# m=20;n=30
[root@aliyun tj]# ((m>15&&n>25)) && echo 1 || echo 0
1
[root@aliyun tj]# ((m>15||n>25)) && echo 1 || echo 0  
1
[root@aliyun tj]# ((m>25||n>25)) && echo 1 || echo 0 
1
[root@aliyun tj]# ((m>25||n>35)) && echo 1 || echo 0 
0
[root@aliyun tj]# ((m>25 -a n>35)) && echo 1 || echo 0  
-bash: ((: m>25 -a n>35: syntax error in expression (error token is "n>35")
0


示例總結:

  • 「-a」和「-o」邏輯操做符號須要用於[]中

  • 「&&」和「||」邏輯操做符號可用於[[]]或(())中,也能夠在外部鏈接多個[]

  •  注意,在[]和[[]]的兩端及比較符號的兩端,必需要有空格,可是對於(())不須要




六:測試表達式test、[]、[[]]、(())的區別總結


以下表所示:


測試表達式操做符


           []


        test


          [[]]

    

          (())


邊界是否須要空格


        須要


        須要


         須要


       不須要


邏輯操做符


   !、-a、-o


    !、-a、-o


    !、&&、||


    !、&&、||

整數比較操做符

-eq、-gt、-lt、-ge、-le

-eq、-gt、-lt、-ge、-le

-eq、-gt、-lt、-ge、-le或=、>、<、>=、<=

=、>、<、>=、<=


字符串比較操做符


   =、==、!=


   =、==、!=


  =、==、!=


  =、==、!=


是否支持通配匹配符


      不支持


      不支持


      支持


      不支持

相關文章
相關標籤/搜索