2015/03/18

bash 判斷式

在 bash 環境下,可以使用 test 條件判斷 && 成立時執行 || 不成立時執行,例如
test 1 -eq 1 && echo "good" || echo "bad"
因為 1 永遠等於 1 ,所以上式會輸出 good
寫在 shell script 裡面,會用 [ ] 來表示判斷式,例如上面的例子就會變成
[ 1 -eq 1 ] &&
{
    echo "good"
} || {
    echo "bad"
}

或用另外一種 if 條件判斷的結構
if [ 1 -eq 1 ]; then
    echo "good"
else
    echo "bad"
fi

檔案存在

-e    檔名是否存在(無論是檔案或資料夾)
    [ -e "/etc/resolv.conf" ] 會去檢查 /etc/resolv.conf 是否存在,存在則傳回 .TRUE. 不存在則傳回 .FALSE.
-f    檔名是否以檔案存在
    [ -f "/etc/resolv.conf" ] 會去檢查 /etc/resolve.conf 是否存在而且為檔案
-d    檔名是否以資料夾存在
    [ -d "/etc/ppp" ] 會去檢查 /etc/ppp 是否存在而且是個資料夾
-b    檔名是否以 block device 存在
    [ -b "/dev/sda" ] 會去檢查 /etc/sda 是否存在,而且是個 block device
-c    檔名是否以 character device 存在
    [ -c "/dev/tty" ] 會去檢查 /dev/tty 是否存在,而且是個 character device
-S    檔名是否以 socket 存在
    [ -S "/tmp/.X11-unix/X0" ] 會去檢查 /tmp/.X11-unix/X0 是否存在,而且是個 socket file
-p    檔名是否以 FIFO (pipe) 存在
    [ -p "/tmp/mypipe" ] 會去檢查 /tmp/mypipe 是否存在,而且是個 FIFO file
-L    檔名是否以連結方式存在
    [ -L "/tmp" ] 會去檢查 /tmp 是否存在,而且是個連結
block device 是一種以 block 為單位傳輸的裝置,因此每次傳輸都會是 block 的倍數,屬於固定長度傳輸。主要用於隨機存取裝置,例如硬碟、光碟機。而 Character Device 則是以字元為傳輸單位,屬於非固定長度傳輸。主要用於印表機,終端機...。

檔案權限與屬性

-r    檔名是否存在,而且具有讀取權限
    [ -r "/etc/resolv.conf" ] 會去檢查 /etc/resolv.conf 是否存在,而且具有可讀取的權限
-w    檔名是否存在,而且具有寫入權限
    [ -w "/etc/resolv.conf" ] 會去檢查 /etc/resolv.conf 是否存在,而且具有可寫入的權限
-x    檔名是否存在,而且具有執行權限
    [ -x "/bin/busybox" ] 會去檢查 /bin/busybox 是否存在,而且具有可執行的權限
-u    檔名是否存在,而且具有 SUID 屬性
    [ -u "/etc/resolv.conf" ] 會去檢查 /etc/resolv.conf 是否存在,而且具有 SUID 屬性
-g    檔名是否存在,而且具有 SGID 屬性
    [ -g "/etc/resolv.conf" ] 會去檢查 /etc/resolv.conf 是否存在,而且具有 SGID 屬性
-k    檔名是否存在,而且具有 Sticky bit 屬性
    [ -k "/etc/resolv.conf" ] 會去檢查 /etc/resolv.conf 是否存在,而且具有 Sticky bit 屬性
-s    檔名存在,而且不是空白檔案
    [ -s "/etc/resolv.conf" ] 會去檢查 /etc/resolv.conf 是否存在,而且不是空白檔案

整數比較判斷

-eq    兩個整數是否相等 (equal)
    [ $n1 -eq $n2 ]
-ne    兩個整數是否不相等 (not equal)
    [ $n1 -ne $n2 ]
-gt    n1 是否大於 n2 (greater then)
    [ $n1 -gt $n2 ]
-lt    n1 是否小於 n2 (lesser then)
    [ $n1 -lt $n2 ]
-ge    n1 是否大於等於 n2 (greater then or equal)
    [ $n1 -ge $n2 ]
-le    n1 是否小於等於 n2 (lesser then or equal)
    [ $n1 -le $n2 ]

字串判斷

-z    判斷是否為空字串
    [ -z "$str1" ]    檢查 str1 是不是空字串,是空字串傳回 .TRUE.,否則傳回 .FALSE.
-n    判斷是否不是空字串,跟 -z 剛好相反
    [ -n "$str1" ]    檢查 str1 是不是空字串,是空字串傳回 .FALSE.,否則傳回 .TRUE.
==    判斷字串是否相等
    [ "$str1" == "$str2" ]
!=    判斷字串是否不相等
    [ "$str1" != "$str2" ]

其他邏輯

-a    前後兩個條件用 and 作邏輯運算
    [ $n1 -eq $n2 -a "$str1" == "$str2" ]
-o    前後兩個條件用 or 作邏輯運算
    [ $n1 -eq $n2 -o "$str1" == "$str2" ]
!    反相邏輯運算
    [ ! -e "/etc/resolve.conf" ]

習慣與注意事項

因為 bash 在很多地方會把空格當成隔開的符號,尤其是條件判斷式的每個單元都要用空格格開,包含前後的括號 [ ] ,所以 [ 1 -eq 1 ] 不能寫成 [1 -eq 1]。而變數內往往也會存在空白符號,所以用在字串判斷的時候,最好能養成習慣把變數用 "" 刮起來,例如 "$str1"。舉個例子來說
    str1="This is a book."
    [ $str1 == "This is a book" ]

因為 $str1 會變成 This is a book 而不是 "This is a book" 所以上式會變成 [ This is a book == "This is a book" ],會造成參數解析上的錯誤,所以還是養成習慣,只要遇到字串變數,都加上 "",如上例寫成 [ "$str1" == "This is a book." ] 就不會出錯了。

沒有留言: