在Bash中使用[方括號](二)
我們繼續來看方括號的用法,它們甚至還可以在 Bash 當中作為一個命令使用。
歡迎回到我們的方括號專題。在前一篇文章當中,我們介紹了方括號在命令行中可以用于通配操作,如果你已經讀過前一篇文章,就可以從這里繼續了。
方括號還可以以一個命令的形式使用,就像這樣:
[ "a" = "a" ]
上面這種 [ ... ]
的形式就可以看成是一個可執行的命令。要注意,方括號內部的內容 "a" = "a"
和方括號 [
、]
之間是有空格隔開的。因為這里的方括號被視作一個命令,因此要用空格將命令和它的參數隔開。
上面這個命令的含義是“判斷字符串 "a"
和字符串 "a"
是否相同”,如果判斷結果為真,那么 [ ... ]
就會以狀態碼 0 退出,否則以狀態碼 1 退出。在之前的文章中,我們也有介紹過狀態碼的概念,可以通過 $?
變量獲取到最近一個命令的狀態碼。
分別執行
[ "a" = "a" ]
echo $?
以及
[ "a" = "b" ]
echo $?
這兩段命令中,前者會輸出 0(判斷結果為真),后者則會輸出 1(判斷結果為假)。在 Bash 當中,如果一個命令的狀態碼是 0,表示這個命令正常執行完成并退出,而且其中沒有出現錯誤,對應布爾值 true
;如果在命令執行過程中出現錯誤,就會返回一個非零的狀態碼,對應布爾值 false
。而 [ ... ]
也同樣遵循這樣的規則。
因此,[ ... ]
很適合在 if ... then
、while
或 until
這種在代碼塊結束前需要判斷是否達到某個條件結構中使用。
對應使用的邏輯判斷運算符也相當直觀:
[ STRING1 = STRING2 ] => 檢查字符串是否相等
[ STRING1 != STRING2 ] => 檢查字符串是否不相等
[ INTEGER1 -eq INTEGER2 ] => 檢查整數 INTEGER1 是否等于 INTEGER2
[ INTEGER1 -ge INTEGER2 ] => 檢查整數 INTEGER1 是否大于等于 INTEGER2
[ INTEGER1 -gt INTEGER2 ] => 檢查整數 INTEGER1 是否大于 INTEGER2
[ INTEGER1 -le INTEGER2 ] => 檢查整數 INTEGER1 是否小于等于 INTEGER2
[ INTEGER1 -lt INTEGER2 ] => 檢查整數 INTEGER1 是否小于 INTEGER2
[ INTEGER1 -ne INTEGER2 ] => 檢查整數 INTEGER1 是否不等于 INTEGER2
等等……
方括號的這種用法也可以很有 shell 風格,例如通過帶上 -f
參數可以判斷某個文件是否存在:
for i in {000..099}; \
do \
if [ -f file$i ]; \
then \
echo file$i exists; \
else \
touch file$i; \
echo I made file$i; \
fi; \
done
如果你在上一篇文章使用到的測試目錄中運行以上這串命令,其中的第 3 行會判斷那幾十個文件當中的某個文件是否存在。如果文件存在,會輸出一條提示信息;如果文件不存在,就會把對應的文件創建出來。最終,這個目錄中會完整存在從 file000
到 file099
這一百個文件。
上面這段命令還可以寫得更加簡潔:
for i in {000..099};\
do\
if [ ! -f file$i ];\
then\
touch file$i;\
echo I made file$i;\
fi;\
done
其中 !
運算符表示將判斷結果取反,因此第 3 行的含義就是“如果文件 file$i
不存在”。
可以嘗試一下將測試目錄中那幾十個文件隨意刪除幾個,然后運行上面的命令,你就可以看到它是如何把被刪除的文件重新創建出來的。
除了 -f
之外,還有很多有用的參數。-d
參數可以判斷某個目錄是否存在,-h
參數可以判斷某個文件是不是一個符號鏈接。可以用 -G
參數判斷某個文件是否屬于某個用戶組,用 -ot
參數判斷某個文件的***更新時間是否早于另一個文件,甚至還可以判斷某個文件是否為空文件。
運行下面的幾條命令,可以向幾個文件中寫入一些內容:
echo "Hello World" >> file023
echo "This is a message" >> file065
echo "To humanity" >> file010
然后運行:
for i in {000..099};\
do\
if [ ! -s file$i ];\
then\
rm file$i;\
echo I removed file$i;\
fi;\
done
你就會發現所有空文件都被刪除了,只剩下少數幾個非空的文件。
如果你還想了解更多別的參數,可以執行 man test
來查看 test
命令的 man 手冊(test
是 [ ... ]
的命令別名)。
有時候你還會看到 [[ ... ]]
這種雙方括號的形式,使用起來和單方括號差別不大。但雙方括號支持的比較運算符更加豐富:例如可以使用 ==
來判斷某個字符串是否符合某個模式,也可以使用 <
、>
來判斷兩個字符串的出現順序。
可以在 Bash 表達式文檔中了解到雙方括號支持的更多運算符。