真假值判斷可針對字串、整數、及檔案三大類,並且可以邏輯結合起來。
字串比較
| [ str1 = str2 ] [ str1 == str2 ] |
字串相等 | POSIX 相容 test 指令要用「=」。 |
| [ str1 != str2 ] | 字串不相等 | |
| [ str1 \> str2 ] | 字串大於 | 「\」是 shell 的跳脫字元,消除「>」「<」輸出入轉向之意。 |
| [ str1 \< str2 ] | 字串小於 | |
| [ -z str ] | 空字串,字串長度為 0 | |
| [ str ] [ -n "str" ] |
非空字串,字串長度大於 0 | 兩者結果有些不一樣,似乎 -n 字串前後要加 " 才會對 |
[ "$var" = "" ]
[ ! "$var" ]
[ -z "$var" ]
[ "X${var}" = "X" ]
排序按照 lexicographical,[[ 指令用照 locale 排序,test 指令用 ASCII 順序。
當 == (或 =) 或 != 用在 [[ 指令,右邊是 pattern 進行 Pattern Matching,如同啟用選項 extglob。如果啟用選項 nocasematch,比對不分大小寫。pattern 任何部份可以 quoted 來強迫直接字串比對。
整數比較
| [ n1 -eq n2 ] | 相等 |
| [ n1 -ne n2 ] | 不相等 |
| [ n1 -gt n2 ] | 大於 |
| [ n1 -ge n2 ] | 大於等於 |
| [ n1 -lt n2 ] | 小於 |
| [ n1 -le n2 ] | 小於等於 |
檔案測試
判斷檔案是否存在,或測試檔案的屬性,如類型或權限等。| [ -a file ] | 檔案存在 (和 -e 有何不同?) |
| [ -b file ] | 存在為 block 裝置 |
| [ -c file ] | 存在為 character 裝置 |
| [ -d file ] | 存在為目錄 |
| [ -e file ] | 檔名存在 |
| [ -f file ] | 存在為一般檔案 |
| [ -g file ] | 檔案存在且 set-group-id |
| [ -h file ] | 檔案為 symbolic link (和 -S 有何不同?) |
| [ -k file ] | 存在且有設 sticky bit |
| [ -p file ] | 存在為 named pipe (FIFO) |
| [ -r file ] | 存在為可讀 |
| [ -s file ] | 存在為非空檔案 |
| [ -t fd ] | file descriptor fd is open and refers to a terminal |
| [ -u file ] | 存在且 set-user-id |
| [ -w file ] | 存在為可寫 |
| [ -x file ] | 存在為可執行 |
| [ -G file ] | 存在為 effective group id 擁有 |
| [ -L file ] | 存在為 symbolic link |
| [ -N file ] | 存在,且上次讀取後有更改 |
| [ -O file ] | 存在為擁有者 |
| [ -S file ] | 存在為 socket |
| [ file1 -ef file2 ] | 兩者是否為同一個檔案 (同一個 inode) |
| [ file1 -nt file2 ] | 較新,或 file1 存在 file2 不存在 |
| [ file1 -ot file2 ] | 較舊,或 file1 不存在 file2 存在 |
如果檔案是 /dev/fd/n,檢查 file descriptor n。如果是 /dev/stdin、/dev/stdout、或 /dev/stderr,則分別檢查 file descriptor 0、1、或 2。
其它
-o optname:shell 選項 optname 已啟用。-v varname:shell 變數 varname 已設 (已指定值)。
-R varname:shell 變數 varname 已設且是 name reference.
藉由「-a」(and, 且)、「-o」(or, 或)、「!」(非) 邏輯運算,可結合好幾個真假值判斷:
[ -r filename1 -a -x filename ] ==> 若 filename1 可讀且可執行
[ -r filename1 -o -x filename ] ==> 若 filename1 可讀或可執行
[ ! -r filename1 ] ==> 若 filename1 不是可讀
[[ 不進行 Word splitting 和 pathname expansion。進行 tilde expansion、parameter and variable expansion、arithmetic expansion、command substitution、process substitution、和 quote removal。Conditional operators such as -f must be unquoted to be recognized as primaries.
當 == (或 =) 或 != 用在 [[ 指令,右邊是 pattern 進行 Pattern Matching,如同啟用選項 extglob。如果啟用選項 nocasematch,比對不分大小寫。pattern 任何部份可以 quoted 來強迫直接字串比對。
另外還有額外 binary operator「=~」使用 extended regular expression (regex()),如果 regular expression syntactically 錯誤回傳 2。Substrings matched by parenthesized subexpressions within the regular expression 存在 BASH_REMATCH 陣列,其中 index 0 是整個符合的部份,index n 是第 n 個parenthesized subexpression 符合的部份。
用下列優先權,表示式可以結合:
( expression ):優先進行。
! expression:True if expression is false.
expression1 && expression2:expression1 false 回傳 false,否則看 expression2 是否 true。
expression1 || expression2:expression1 true 回傳 true,否則看 expression2 是否 true。
if-than-elsetest
case
參考:
- 善用判斷式 [鳥哥的 Linux 私房菜]
- 真假值判斷 [Shell 設計入門 by 臥龍小三] mirror
- Shell Script 文章
- man bash 的 CONDITIONAL EXPRESSIONS 段落
- http://mywiki.wooledge.org/BashFAQ/031
- https://stackoverflow.com/questions/3427872/whats-the-difference-between-and-in-bash
沒有留言:
張貼留言