bash腳本編程之二 條件判斷and 邏輯運算


1、條件測試結構

 1) if/then結構:

 判斷命令列表的退出碼是否為0,0為成功。

 如果if和then在條件判斷的同一行上的話, 必須使用分號來結束if表達式

 if和then都是關鍵字。

 關鍵字(或者命令)如果作為表達式的開頭, 並且如果想在同一行上再寫一個新的表達式的話, 那么必須使用分號來結束上一句表達式。

 

 

if  [ condition1 ]

 

then
     command1
     command2
     command3
elif  [ condition2 ]
then
# 與else if一樣
     command4
     command5
else
     default- command
fi

 

 if/then結構可以包含嵌套的比較操作和條件判斷操作:
if  echo  "Next *if* is part of the comparison for the first *if*."
     if  [[ $comparison = "integer"  ]]
         then  (( a < b ))
     else
         [[ $a < $b ]]
     fi
then
     echo  '$a is less than $b'
fi

 

 

 

2) 內建命令[與test命令等價,把參數作為比較表達式和文件測試,true返回0,false返回1。

 

注意:[ 數字 ]、[ 字符串 ]都為真,NULL(空狀態)、未未定義(或者叫為初始化的變量)、初始化但賦值為null的變量為假

 

3) bash2.02以后支持[[..]]關鍵字,比[]結構更加通用

在[[]]之間所有的字符都不會發生文件名擴展或者單詞分割,但是會發生參數擴展和命令替換;使用[[]]能防止腳本中的很多邏輯錯誤,比如 &&, ||, <, >操作符能正常存在於[[]]中,如果出現在[]中會報錯。

 

 

if  [ $a = "123"  && $b = "456"  ]; then  // 報錯

 

     echo  "True"
else
     echo  "False"
fi
 
if  [[ $a = "123"  && $b = "456"  ]]; then  // 正確
     echo  "True"
else
     echo  "False"
fi
 
if  [ $a = "789"  || $b = "456"  ]; then  // 報錯
     echo  "True"
else
     echo  "False"
fi
 
if  [[ $a = "789"  || $b = "456"  ]]; then  // 正確
     echo  "True"
else
     echo  "False"
fi
 
if  [ $a < $b ]; then  // 報錯
     echo  "True"
else
     echo  "False"
fi
 
if  [[ $a < $b ]]; then  // 正確
     echo  "True"
else
     echo  "False"
fi

 

 

 

4) 列表結構

 

在中括號中的條件判斷不一定非得有if

1
2
[ "$var1"  - ne  "$var2"  ] && echo  "$var1 is not equal to $var2"
[ -d "$home"  ] || echo  "$home directory does not exist."

雙中括號也是可以的

5) ((…))和let …, 當算數表達式的結果非零時,返回退出狀態碼0

2、文件測試操作符

-e 文件存在

-f  一個一般文件(不是目錄或者設備文件)

-s 文件大小不為0

-d 一個目錄

-b 塊設備

-c 字符設備

-p 管道

-h or –L 符號鏈接

-S socket

-t 文件描述符被關聯到一個終端設備上,一般用來檢測stdin([ -t 0 ])和stdout([ -t 1 ])是否來自於一個終端

-r 文件是否具有可讀權限

-w 文件是否具有可寫權限

-x 文件是否具有可執行權限

-u set-user-id (suid)標記被設置到文件上。如果一個root用戶所擁有的二進制可執行文件設置了set-user-id標記位的話, 那么普通用戶也會以root權限來運行這個文件。

對於設置了suid標志的文件, 在它的權限列中將會以s表示。注意這樣可能導致安全漏洞

-k 設置粘貼位

對於"粘貼位"的一般了解, save-text-mode標志是一個文件權限的特殊類型。如果文件設置了這個標志, 那么這個文件將會被保存到緩存中, 這樣可以提高訪問速度。粘貼位如果設置在目錄中, 那么它將限制寫權限. 對於設置了粘貼位的文件或目錄, 在它們的權限標記列中將會顯示t。在當代unix系統中,文件已經不使用粘貼位,只在目錄中用

-N 從文件上一次被讀取到現在為止,文件是否被修改過

f1 –nt f2 文件f1比文件f2新

f1 –ot f2 文件f1比文件f2舊

f1 –ef f2 文件f1和f2是相同文件的硬鏈接

! 翻轉測試結果

3、其他比較操作符

1) 整數比較

在中括號中使用:-eq、-ne、-gt、-ge、-lt、-le

在雙小括號中使用:<、<=、>、>=

2) 字符串比較

=與==等價。注意,==在雙中括號和單中括號中行為不同:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
a= "zabc"
[[ $a == z* ]] # 如果$a以"z"開頭(模式匹配)那么結果將為真
[[ $a == "z*"  ]] # 如果$a與z*相等(就是字面意思完全一樣), 那
么結果為真.
 
a=abc.conf #abc.conf is a file
[ $a == abc* ] # 文件擴展匹配(file globbing)和單詞分割有
效.True
a= "abcdef"  #just a string, not a file
[ $a == abc* ] #False
 
[ "$a"  == "z*"  ] # 如果$a與z*相等(就是字面意思完全一樣), 那
么結果為真.
 
#總結起來,[]的使用很危險,存在各種可能的擴展,如果要用,最好對變量加上引號

!=,不等,在[[]]中使用模式匹配

<、>在[]結構中要轉義

-z 字符串為null,就是字符串長度為0

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash
a= "hello"
b= ""
c=
[ -z $a ] && echo  "a null"
[ -z $b ] && echo  "b null"
[ -z $c ] && echo  "c null"
[ -z $d ] && echo  "d null"
 
#結果
#b null
#c null
#d null

-n 字符串不為null。當-n使用在中括號中進行條件測試的時候, 必須要把字符串用雙引號引用起來。

-a 邏輯與。 exp1 –a exp2; -o 邏輯或 exp1 –o exp2;這與Bash中的比較操作符&&和||非常相像, 但是&&和||是用在雙中括號結構中的。

特別注意:在一個混合測試中, 即使使用引用的字符串變量也可能還不夠。如果$string為空的話, [ -n "$string" -o "$a" = "$b" ]可能會在某些版本的Bash中產生錯誤. 安全的做法是附加一個額外的字符給可能的空變量, [ "x$string" != x -o "x$a" = "x$b" ] ("x"字符是可以相互抵消的).

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM