1. 程式人生 > 其它 >shell條件測試

shell條件測試

一般使用shell處理的條件測試型別有三種:

檔案測試

數值比較

字串比較

檔案運算比較符 表示式 含義
-e -e filename 如果 filename 存在,則為真
-d -e filename 如果 filename 為目錄,則為真
-f -e filename 如果 filename 為常規檔案
-L -e filename 如果 filename 為符號連結,則為真
-r -e filename 如果 filename 可讀,則為真
-w -e filename 如果 filename 可寫,則為真
-x -e filename 如果 filename 可執行,則為真
-ot filename1 -ot filename2 如果 filename1 比 filename2 舊,則為真
-nt filename1 -nt filename2 如果 filename1 比 filename2 新,則為真
字串運算比較符 表示式 含義
-z -z string 如果 string 長度為零,則為真
-n -n string 如果 string 長度非零,則為真
= string1 = string2 如果 string1 與 string2 相同,則為真
!= string1 != string2 如果 string1 與 string2 不同,則為真
算術比較運算子 表示式 含義
-eq num1 -eq num2 如果num1等於num2,則為真
-ne num1 -ne num2 如果num1不等於num2,則為真
-lt num1 -lt num2 如果num1小於num2,則為真
-le num1 -le num2 如果num1小於等於num2,則為真
-gt num1 -gt num2 如果num1大於num2,則為真
-ge num1 -ge num2 如果num1大於等於num2,則為真
== num1 == num2 如果num1等於num2,則為真
!= num1 != num2 如果num1不等於num2,則為真
>= num1 >= num2 如果num1大於等於num2,則為真
<= num1 <= num2 如果num1小於等於num2,則為真
> num1 > num2 如果num1大於num2,則為真
< num1 < num2 如果num1小於num2,則為真

處理條件測試的方式有以下幾種

用法 適用範圍 是否支援正則 備註
test test 條件表示式 檔案測試、數值比較、字串比較
[ ] [ 條件表示式 ] 檔案測試、數值比較、字串比較 注意空格
[[ ]] [[ 條件表示式 ]] 檔案測試、數值比較、字串比較
(( )) (( 表示式 )) 數值比較 注意千萬不要用於字串比較;當表示式單為數字時,0返假,其他全部為真

幾種處理方式異同,及需要注意的點具體如下:

一、test

test和[ ] 幾乎等價可以檔案測試、數值比較、字串比較。不過在進行數字比較時可以用的運算字元只有"-eq",“-ne”,“-lt”,“-le”,“-gt”,“-ge”,“==”,“!=”。

他的優點是:三種條件測試都能可以做,而且是內部命令(所以指令碼中可不要定義名為test的變數)。因此,使用範圍廣,大多數shell都支援。

它的缺點是不支援正則,還有語句不夠清晰明瞭,沒有[ ]簡潔,易讀。

示例:

1、檔案測試

# vim test.sh
if test -d /etc then echo "11111111111111" else echo "22222222222222" fi

  

2、字串比較測試

if test qaw == aqw
then
    echo "11111111111111"
else
    echo "22222222222222"
fi

 

3、數值比較測試

if test 111 -eq 111
then
    echo "11111111111111"
else
    echo "22222222222222"
fi

  

4、當後面表示式直接接字串或者數字時

if test 1111
then
    echo "11111111111111"
else
    echo "22222222222222"
fi

  

if test qqqq
then
    echo "11111111111111"
else
    echo "22222222222222"
fi

 

直接接字串時,直接判定為真

5、後面直接接0

if test 0
then
    echo "11111111111111"
else
    echo "22222222222222"
fi

  

6、後面不接表示式

if test
then
    echo "11111111111111"
else
    echo "22222222222222"
fi

不接表示式直接判定為假

二、[ ]

[ ] 和test等價,優缺點幾乎相同。但是 [ ] 比test的表示式顯然更方便閱讀。不過在使用 [ ]千萬不要吝嗇空格。

可以看下缺少空格的幾種情況

1、中括號兩邊不加空格

vari1=0
vari2=1
if [${vari1} == ${vari2}]
then
    echo "11111111111111"
else
    echo "22222222222222"
fi

可以看到會報語法錯誤,並且指令碼還會執行下去,並且會預設判斷為假

2、運算子中間不加空格

vari1=0
vari2=1
if [ ${vari1}==${vari2} ]
then
    echo "11111111111111"
else
    echo "22222222222222"
fi

不會報錯,並且會預設為真(應該是當字串處理了)。這點需要注意,會導致指令碼達不到預期處理效果。

其他一些特殊情況,如表示式為空,表示式為0等情況和test完全一樣

3、如果誤使用了 ">" , "<",”>=“,"<="這些算術。

[ ] 會把 ”>“ 和 ”<“當重定向識別了.........

當使用”>“和”<“時

vari1=0
vari2=1
if [ ${vari1} > ${vari2} ]
then
    echo "11111111111111"
else
    echo "22222222222222"
fi

指令碼執行並沒有報錯。但是輸出的結果錯誤,看下具體執行過程

可以看到他判斷的物件只有${vari1}即”0“,所以返回結果為真。

不過這種情況可以使用 '' 或者 ”“ 或者 轉義符 \ 來避免。不過確實時太麻煩了,而且容易出錯

當誤使用">="和”<=“時。

vari1=0
vari2=1
if [ ${vari1} >= ${vari2} ]
then
    echo "11111111111111"
else
    echo "22222222222222"
fi

指令碼執行會直接報錯。

這種情況使用引號或者轉義符也不能避免

所以當使用[ ] 時。數值的判斷最好好養成習慣使用"-eq",“-ne”,“-lt”,“-le”,“-gt”,“-ge”。不然當碰到那些不報錯的情況時,排錯都不好排。

三、[[ ]]

[[ ]]其實相當於[ ]的擴充套件,支援字串的模式匹配,使用=~操作符時甚至支援shell的正則表示式!邏輯組合可以不使用test的-a,-o而使用&&,||這樣更親切的形式(針對c、Java程式設計師)。也可以使用運算子 >、<。

但是同樣的,它的使用也要十分注意空格。

基本使用和 [ ] 一樣,依然說一些比較特殊,或者不同的情況。

1、也可以使用運算子 >、<

vari1=0
vari2=1
if [[ ${vari1} > ${vari2} ]]
then
    echo "11111111111111"
else
    echo "22222222222222"
fi

但是對於二元運算子”>=“和”<=“仍不可使用,並且會直接報錯

vari1=0
vari2=1
if [[ ${vari1} >= ${vari2} ]]
then
    echo "11111111111111"
else
    echo "22222222222222"
fi

2、可以使用邏輯運算子 &&,||,!

但是這裡有個大坑

if [[ a != b && 5 > 3 ]]
then
    echo "11111111111111"
else
    echo "22222222222222"
fi

數字比較,結果正確。但有時候

if [[ a != b && 15 > 3 ]]
then
    echo "11111111111111"
else
    echo "22222222222222"
fi

???????????????????

結果就會很奇怪

其實不光在[[ ]]中,在 [ ] 使用也是如此

所以在shell指令碼中,數值的判斷最好好養成習慣使用"-eq",“-ne”,“-lt”,“-le”,“-gt”,“-ge”。

另外,其實如果兩個數是相同位數時,結果不會錯。

”>“的判定邏輯有點奇怪,比較像sort。只會判斷第一位數的大小。而不會管這個數是幾位數。所以儘量還是不要用,畢竟在指令碼中大多是變數比較,而我們無法確定要比較的兩個變數位數是否相同。

3、支援萬用字元擴充套件

if [[ hello = hell? ]]
then
    echo "11111111111111"
else
    echo "22222222222222"
fi

4、當表示式為空。會直接報錯

5、當表示式為0,或者其他時。預設為真,並且可以看到預設為 [[ -n ]]

if [[ 0 ]]
then
    echo "11111111111111"
else
    echo "22222222222222"
fi

四、(( ))

(( ))只適用於數值比較,裡面語法比較接近C,JAVA程式設計成語言。可以不加空格(也可以加),變數可以不加$或${}(也可以加)。支援算術運算子,賦值運算子,邏輯運算子,位運算子,條件運算子。

1、不加$,${} 和空格

vari1=55
vari2=200
if ((vari1>vari2))
then
    echo "11111111111111"
else
    echo "22222222222222"
fi

加上${}和空格

vari1=55
vari2=200
if (( ${vari1} > ${vari2} ))
then
    echo "11111111111111"
else
    echo "22222222222222"
fi

可以看到結果並無差別。不過還是建議用shell格式,統一比較好

2、賦值運算。=

[[ ]]和[ ] 中"="和”==”好像並無差別,但是(( )) 中“=”屬於賦值運算子,“=="才是關係運算符

vari1=55
vari2=200
if ((vari1=vari2))
then
    echo $vari1
    echo "11111111111111"
else
    echo "22222222222222"
vari1=55
vari2=200
if ((vari1==vari2))
then
    echo $vari1
    echo "11111111111111"
else
    echo "22222222222222"

而且對於賦值運算子"=" 兩邊不能有空格。而關係運算符 ”==“可以有,也可以沒有空格

3、賦值運算

(( ))其實也可以單獨拿出來做數字的計算

4、邏輯運算子

vari1=200
vari2=200
vari3=200
vari4=200
if (( ${vari1} == ${vari2} && ${vari3} == ${vari4} ))
then
    echo
    echo "11111111111111"
else
    echo "22222222222222"
fi

邏輯短路

vari1=200
vari2=200
vari3=200
vari4=201
if (( ${vari1} == ${vari2} == ${vari3} == ${vari4} ))
then
    echo "11111111111111"
else
    echo "22222222222222"
fi

這一點在比較多個數的時候非常方便。

如果是用[[ ]]的話只能寫為[[ ${vari1} == ${vari2} && ${vari2} == ${vari3} && ${vari3} == ${vari4} ]]或者[[{vari1} == ${vari2} ]] && [[${vari2} ==${vari3} ]] && [[${vari3}== ${vari4} ]]

而用[ ] 的話只能寫為 [ ${vari1} == ${vari2} ] && [ ${vari2} == ${vari3} ] && [ ${vari3} == ${vari4} ]

5、表示式為空時

vari1=200
vari2=200
vari3=200
vari4=201
if (())
then
    echo "11111111111111"
else
    echo "22222222222222"
fi

6、表示式為0時

if ((0))
then
    echo "11111111111111"
else
    echo "22222222222222"
fi

這裡和[[ ]] 以及[ ] 不同。(( ))語法和C語言差不多,所以為0時,會直接判定為假。

而其他數字(包括負數) ,都會判定為真

7、表示式誤寫為字母時,預設判定為假

if ((edkio))
then
    echo "11111111111111"
else

這裡應該也是和C語言語法有關,在C語言中,沒有定義的變數值預設為0。由於雙括號中變數也可以不加$或者${},所以edkio預設認為時變數