shell test 條件表達式對于很多的開發者來講都是不很理解了,下文我來為各位介紹一些關于linux中shell test 條件表達式的說明與例子.
條件表達式("CONDITIONAL EXPRESSIONS")
條件表達式用于 [[ 復合命令以及內建命令 test 和 [ 中,用來測試文件屬性,進行字符串和算術比較,表達式使用下面的單目或二進制操作構造,如果某操作的任何 file 參數的形式是.
文件符號:在info bash里的第“6.4 Bash Conditional Expressions”節里開頭有一句話說明了shell條件判斷的二個機制:
Conditional expressions are used by the `[[' compound command and the
機制一:內置(builtin)的函數test(運算符[]),此部分完整的說明,可查看“4.1 Bourne Shell Builtins”
機制二:[[]],條件結構關健字,具體可查看“3.2.4.2 Conditional Constructs”
test跟[]是一回事,只不過一個以函數的形式,一個以成對操作符的形式出現,test包含6.4節條件表達式的表達形式,是函數就有參數,test對1、2、3.。。6等多個參數的判斷分別進行定義,而[[]],大部分的功能跟[]是一樣的,可以簡單理解成[]的擴展,但對于參數的判斷定義上,比test有更完整的定義,不容易出現[]中的錯誤,比如在-eq比較的右操作符中,[]要求右操作符不為空,否則報錯,返回2,而[[]]則不會.
- [root@localhost tmp]# [ 1 -eq $a ]
- + '[' 1 -eq ']'
- -bash: [: 1: unary operator expected
- [root@localhost tmp]# echo $?
- + echo 2
- 2
- [root@localhost tmp]# [[ 1 -eq $a ]]
- + [[ 1 -eq '' ]]
- [root@localhost tmp]# echo $?
- + echo 1
- 1
這也是很多程序員喜歡用[[]]的原因,不容易出錯,test的表達能力,[[]]擴展了二個功能.
1:pattern match,通配符匹配,采用雙等號“==”
2:regex match,正則匹配,采用“=~”運算符號
首先說明下通配符匹配:先說明一下[]里的==運算,[]也包括==比較,用于字符串相等比較,同樣,==號在這里也不允許右操作符為空,否則報錯.
- [root@localhost tmp]# [ "abc" == $a ]
- + '[' abc == ']'
- -bash: [: abc: unary operator expected
解決辦法是加個引號:
- [root@localhost tmp]# [ "abc" == "$a" ]
- + '[' abc == '' ']'
而[[]]里的==,在3.2.4.2 里有介紹:
- When the `==' and `!=' operators are used, the string to the right
- of the operator is considered a pattern and matched according to
- the rules described below in *Note Pattern Matching::。。。
- Any part of the pattern may be quoted
- to force it to be matched as a string.
這一段說明至少要注意二點:
1:[[]]里的==運算符,把所有右操作符都看做是一個pattern,==實際上不只是簡單字符串比較,而是pattern match,即通配符匹配,具體的規則可以參考
3.5.8.1 Pattern Matching
2:最后一句:引號可以直接定義字符串,在3.5.8.1里也有一句話:The special pattern
characters must be quoted if they are to be matched literally.
即:pattern特殊字符為字符在引號里取消特殊定義
這也就能解釋下邊的二個例子的差別了:
- [root@localhost tmp]# set -x
- + set -x
- [root@localhost tmp]# [[ abc == a*c ]]
- + [[ abc == a*c ]]
- [root@localhost tmp]# echo $?
- + echo 0
- 0
- [root@localhost tmp]# [[ abc == "a*c" ]]
- + [[ abc == /a/*/c ]]
- [root@localhost tmp]# echo $?
- + echo 1
- 1
另外需要留意下:在[[里,文檔中提到:
- Word splitting and filename expansion are not
- performed on the words between the `[[' and `]]'; tilde expansion,
- parameter and variable expansion, arithmetic expansion, command
- substitution, process substitution, and quote removal are
- performed.
也就是說,在[[里,不進行bash命令解析中的“文字分割Word splitting ” 和 “文件名擴展filename expansion ”但還是進行了 “~符號擴展,參數和變量擴展,算術擴展,命令替換,進程替換,引號去除”,所以不必擔心上邊例子中,a*b是否會擴展成目錄下的文件名.
至于=~正則匹配,就沒有什么特別是的了,右操作數直接定義成一個正則式子即是,這里正則的引號可用可不用(不能用/),因為在 “quote removal ”環節,對非擴展出來的引號做了去除處理,實際上有加引號與不加引號是一樣的結果.
- [root@localhost tmp]# [[ abc =~ 'ab*c' ]]
- + [[ abc =~ ab*c ]]
- [root@localhost tmp]# echo $?
- + echo 0
- 0
- [root@localhost tmp]# [[ abc =~ "ab*c" ]]
- + [[ abc =~ ab*c ]]
- [root@localhost tmp]# echo $?
- + echo 0
- 0
- [root@localhost tmp]# [[ abc =~ ab*c ]]
- + [[ abc =~ ab*c ]]
- [root@localhost tmp]# echo $?
- + echo 0 --Vevb.com
- 0
- [root@localhost tmp]# [[ abc =~ /ab*c/ ]]
- + [[ abc =~ /ab*c/ ]]
- [root@localhost tmp]# echo $?
- + echo 1
- 1
例子:
- [root@LAMP test]# help test
- test: test [expr]
- Evaluate conditional expression.
- Exits with a status of 0 (true) or 1 (false) depending on
- the evaluation of EXPR. Expressions may be unary or binary. Unary
- expressions are often used to examine the status of a file. There
- are string operators as well, and numeric comparison operators.
- File operators:
- -a FILE True if file exists.
- -b FILE True if file is block special.
- -c FILE True if file is character special.
- -d FILE True if file is a directory.
- -e FILE True if file exists.
- -f FILE True if file exists and is a regular file.
- -g FILE True if file is set-group-id.
- -h FILE True if file is a symbolic link.
- -L FILE True if file is a symbolic link.
- -k FILE True if file has its `sticky' bit set.
- -p FILE True if file is a named pipe.
- -r FILE True if file is readable by you.
- -s FILE True if file exists and is not empty.
- -S FILE True if file is a socket.
- -t FD True if FD is opened on a terminal.
- -u FILE True if the file is set-user-id.
- -w FILE True if the file is writable by you.
- -x FILE True if the file is executable by you.
- -O FILE True if the file is effectively owned by you.
- -G FILE True if the file is effectively owned by your group.
- -N FILE True if the file has been modified since it was last read.
- FILE1 -nt FILE2 True if file1 is newer than file2 (according to
- modification date).
- FILE1 -ot FILE2 True if file1 is older than file2.
- FILE1 -ef FILE2 True if file1 is a hard link to file2.
- String operators:
- -z STRING True if string is empty.
- -n STRING
- STRING True if string is not empty.
- STRING1 = STRING2
- True if the strings are equal.
- STRING1 != STRING2
- True if the strings are not equal.
- STRING1 < STRING2
- True if STRING1 sorts before STRING2 lexicographically.
- STRING1 > STRING2
- True if STRING1 sorts after STRING2 lexicographically.
- Other operators:
- -o OPTION True if the shell option OPTION is enabled.
- ! EXPR True if expr is false.
- EXPR1 -a EXPR2 True if both expr1 AND expr2 are true.
- EXPR1 -o EXPR2 True if either expr1 OR expr2 is true.
- arg1 OP arg2 Arithmetic tests. OP is one of -eq, -ne,
- -lt, -le, -gt, or -ge.
- Arithmetic binary operators return true if ARG1 is equal, not-equal,
- less-than, less-than-or-equal, greater-than, or greater-than-or-equal
- than ARG2.
- Exit Status:
- Returns success if EXPR evaluates to true; fails if EXPR evaluates to
- false or an invalid argument is given.
- -a file
相關參考:
- 如果 file 存在則為真。
- -b file
- 如果 file 存在且為塊設備則為真。
- -c file
- 如果 file 存在且為字符設備則為真。
- -d file
- 如果 file 存在且是一個目錄則為真。
- -e file
- 如果 file 存在則為真。
- -f file
- 如果 file 存在且為普通文件則為真。
- -g file
- 如果 file 存在且是設置組ID的 (sgid) 則為真。
- -h file
- 如果 file 存在且為符號鏈接則為真。
- -k file
- 如果 file 存在且設置了 ‘‘sticky’’ 位 (粘滯位) 則為真。
- -p file
- 如果 file 存在且是一個命名管道 (FIFO) 則為真。
- -r file
- 如果 file 存在且可讀則為真。
- -s file
- 如果 file 存在且大小大于零則為真。
- -t fd 如果文件描述符 fd 是打開的且對應一個終端則為真。
- -u file
- 如果 file 存在且是設置用戶ID的 (suid) 則為真。
- -w file
- 如果 file 存在且可寫則為真。
- -x file
- 如果 file 存在且可執行則為真。
- -O file
- 如果 file 存在且為有效用戶ID所擁有則為真。
- -G file
- 如果 file 存在且為有效組ID所擁有則為真。
- -L file
- 如果 file 存在且為符號鏈接則為真。
- -S file
- 如果 file 存在且為套接字則為真。
- -N file
- 如果 file 存在且上次讀取后被修改過則為真。
- file1 -nt file2
- 如果 file1 比 file2 要新 (根據修改日期),或者如果 file1 存在而 file2 不存在,則為真。
- file1 -ot file2
- 如果 file1 比 file2 更舊,或者如果 file1 不存在而 file2 存在,則為真。
- file1 -ef file2
- 如果 file1 和 file2 指的是相同的設備和 inode 號則為真。
- -o optname
- 如果啟用了 shell 選項 optname 則為真。參見下面對內建命令 set 的 -o 選項的描述中的選項列表。
- -z string
- 如果 string 的長度為 0 則為真。
- -n string
- string 如果 string 的長度非 0 則為真。
- string1 == string2
- 如果字符串相等則為真。= 可以用于使用 == 的場合來兼容 POSIX 規范。
- string1 != string2
- 如果字符串不相等則為真。
- string1 < string2
- 如果 string1 在當前語言環境的字典順序中排在 string2 之前則為真。
- string1 > string2
- 如果 string1 在當前語言環境的字典順序中排在 string2 之后則為真。
- arg1 OP arg2
- OP 是 -eq, -ne, -lt, -le, -gt, 或 -ge 之一。這些算術二進制操作返回真,如果 arg1 與 arg2 分別是相等,不等,小于,小于或等于,大于,大于或等于關系 。 Arg1 和
- arg2 可以是正/負整數。
新聞熱點
疑難解答