linux [] 與 test 命令 進行 條件判斷
以下 摘自 : http://jianlee.ylinux.org/Computer/Shell/shell_test.html
分類參考
檔案狀態測試
-b filename | 當filename 存在並且是塊檔案時返回真(返回0) |
-c filename | 當filename 存在並且是字元檔案時返回真 |
-d pathname | 當pathname 存在並且是一個目錄時返回真 |
-e pathname | 當由pathname 指定的檔案或目錄存在時返回真 |
-f filename | 當filename 存在並且是正規檔案時返回真 |
-g pathname | 當由pathname 指定的檔案或目錄存在並且設定了SGID 位時返回真 |
-h filename | 當filename 存在並且是符號連結檔案時返回真 (或 -L filename) |
-k pathname | 當由pathname 指定的檔案或目錄存在並且設定了"粘滯"位時返回真 |
-p filename | 當filename 存在並且是命名管道時返回真 |
-r pathname | 當由pathname 指定的檔案或目錄存在並且可讀時返回真 |
-s filename | 當filename 存在並且檔案大小大於0 時返回真 |
-S filename | 當filename 存在並且是socket 時返回真 |
-t fd | 當fd 是與終端裝置相關聯的檔案描述符時返回真 |
-u pathname | 當由pathname 指定的檔案或目錄存在並且設定了SUID 位時返回真 |
-w pathname | 當由pathname 指定的檔案或目錄存在並且可寫時返回真 |
-x pathname | 當由pathname 指定的檔案或目錄存在並且可執行時返回真 |
-O pathname | 當由pathname 存在並且被當前程序的有效使用者id 的使用者擁有時返回真(字母O 大寫) |
-G pathname | 當由pathname 存在並且屬於當前程序的有效使用者id 的使用者的使用者組時返回真 |
file1 -nt file2 | file1 比file2 新時返回真 |
file1 -ot file2 | file1 比file2 舊時返回真 |
f1 -ef f2 | files f1 and f2 are hard links to the same file |
舉例: if [ -b /dev/hda ] ;then echo "yes" ;else echo "no";fi // 將列印 yes
test -c /dev/hda ; echo $? // 將列印 1 表示test 命令的返回值為1,/dev/hda 不是字元裝置
[ -w /etc/passwd ]; echo $? // 檢視對當前使用者而言,passwd 檔案是否可寫
測試時邏輯操作符
-a | 邏輯與,操作符兩邊均為真,結果為真,否則為假。 |
-o | 邏輯或,操作符兩邊一邊為真,結果為真,否則為假。 |
! | 邏輯否,條件為假,結果為真。 |
舉例: [ -w result.txt -a -w score.txt ] ;echo $? // 測試兩個檔案是否均可寫
常見字串測試
-z string | 字串string 為空串(長度為0)時返回真 |
-n string | 字串string 為非空串時返回真 |
str1 = str2 | 字串str1 和字串str2 相等時返回真 |
str1 == str2 | 同 = |
str1 != str2 | 字串str1 和字串str2 不相等時返回真 |
str1 < str2 | 按字典順序排序,字串str1 在字串str2 之前 |
str1 > str2 | 按字典順序排序,字串str1 在字串str2 之後 |
舉例: name="zqf"; [ $name = "zqf" ];echo $? // 列印 0 表示變數name 的值和字串"zqf"相等
常見數值測試
int1 -eq int2 | 如果int1 等於int2,則返回真 |
int1 -ne int2 | 如果int1 不等於int2,則返回真 |
int1 -lt int2 | 如果int1 小於int2,則返回真 |
int1 -le int2 | 如果int1 小於等於int2,則返回真 |
int1 -gt int2 | 如果int1 大於int2,則返回真 |
int1 -ge int2 | 如果int1 大於等於int2,則返回真 |
在 (()) 中的測試:
< | 小於(在雙括號裡使用) | (("$a" < "$b")) |
<= | 小於等於 (在雙括號裡使用) | (("$a" <= "$b")) |
> | 大於 (在雙括號裡使用) | (("$a" > "$b")) |
>= | 大於等於(在雙括號裡使用) | (("$a" >= "$b")) |
舉例: x=1 ; [ $x -eq 1 ] ; echo $? // 將列印 0 表示變數x 的值等於數字1 x=a ; [ $x -eq "1" ] // shell 列印錯誤資訊 [: a: integer expression expected
test , [] , [[]]
因為 shell 和我們通常程式語言不同,更多的情況是和它互動,總是呼叫別人。 所以有些本屬於程式語言本身的概念在 shell 中會難以理解。"基本功" 不好, 更容易 "犯困" 了,我就是一個 :-) 。
以 bash 為例 (其他相容 shell 差不多):
- test 和 [ 是 bash 的內部命令,GNU/linux 系統的 coreutils 軟體包通 常也帶 /usr/bin/test 和 /usr/bin/[ 命令。如果我們不用絕對路徑指 明,通常我們用的都是 bash 自帶的命令。
- [[ 是 bash 程式語言的關鍵字!
$ ls -l /usr/bin/[ /usr/bin/test -rwxr-xr-x 1 root root 37400 9月 18 15:25 /usr/bin/[ -rwxr-xr-x 1 root root 33920 9月 18 15:25 /usr/bin/test $ type [ [[ test [ is a shell builtin [[ is a shell keyword test is a shell builtin
絕大多數情況下,這個三個功能通用。但是命令和關鍵字總是有區別的。命令和 關鍵字的差別有多大呢?
如果是命令,它就和引數組合為一體被 shell 解釋,那樣比如 ">" "<" 就被 shell 解釋為重定向符號了。關鍵字卻不這樣。
在 [[ 中使用 && 和 ||
[ 中使用 -a 和 -o 表示邏輯與和邏輯或。
[[ 中可以使用萬用字元
arch=i486 [[ $arch = i*86 ]] && echo "arch is x86!"
[[ 中匹配字串或萬用字元,不需要引號
[[ $arch_com = i386 || $ARCH = i*86 ]] && cat >> $TFS_REPO <<EOF [tfs-i386] name=GTES11.3 prelim1 baseurl=${BASEURL}i386/ enabled=1 EOF