歡迎光臨
每天分享高質量文章

在 Bash 中使用[方括號](二) | Linux 中國

我們繼續來看方括號的用法,它們甚至還可以在 Bash 當中作為一個命令使用。

— Paul Brown

 

我們繼續來看方括號的用法,它們甚至還可以在 Bash 當中作為一個命令使用。

歡迎回到我們的方括號專題。在前一篇文章[1]當中,我們介紹了方括號在命令列中可以用於通配操作,如果你已經讀過前一篇文章,就可以從這裡繼續了。

方括號還可以以一個命令的形式使用,就像這樣:

  1. [ "a" = "a" ]

上面這種 [ ... ] 的形式就可以看成是一個可執行的命令。要註意,方括號內部的內容 "a" = "a" 和方括號 [] 之間是有空格隔開的。因為這裡的方括號被視作一個命令,因此要用空格將命令和它的引數隔開。

上面這個命令的含義是“判斷字串 "a" 和字串 "a" 是否相同”,如果判斷結果為真,那麼 [ ... ] 就會以狀態碼status code0 退出,否則以狀態碼 1 退出。在之前的文章[2]中,我們也有介紹過狀態碼的概念,可以透過 $? 變數獲取到最近一個命令的狀態碼。

分別執行

  1. [ "a" = "a" ]
  2. echo $?

以及

  1. [ "a" = "b" ]
  2. echo $?

這兩段命令中,前者會輸出 0(判斷結果為真),後者則會輸出 1(判斷結果為假)。在 Bash 當中,如果一個命令的狀態碼是 0,表示這個命令正常執行完成並退出,而且其中沒有出現錯誤,對應布林值 true;如果在命令執行過程中出現錯誤,就會傳回一個非零的狀態碼,對應布林值 false。而 [ ... ] 也同樣遵循這樣的規則。

因此,[ ... ] 很適合在 if ... thenwhile 或 until 這種在程式碼塊結束前需要判斷是否達到某個條件結構中使用。

對應使用的邏輯判斷運運算元也相當直觀:

  1. [ STRING1 = STRING2 ] => 檢查字串是否相等
  2. [ STRING1 != STRING2 ] => 檢查字串是否不相等
  3. [ INTEGER1 -eq INTEGER2 ] => 檢查整數 INTEGER1 是否等於 INTEGER2
  4. [ INTEGER1 -ge INTEGER2 ] => 檢查整數 INTEGER1 是否大於等於 INTEGER2
  5. [ INTEGER1 -gt INTEGER2 ] => 檢查整數 INTEGER1 是否大於 INTEGER2
  6. [ INTEGER1 -le INTEGER2 ] => 檢查整數 INTEGER1 是否小於等於 INTEGER2
  7. [ INTEGER1 -lt INTEGER2 ] => 檢查整數 INTEGER1 是否小於 INTEGER2
  8. [ INTEGER1 -ne INTEGER2 ] => 檢查整數 INTEGER1 是否不等於 INTEGER2
  9. 等等……

方括號的這種用法也可以很有 shell 風格,例如透過帶上 -f 引數可以判斷某個檔案是否存在:

  1. for i in {000..099}; \
  2. do \
  3. if [ -f file$i ]; \
  4. then \
  5. echo file$i exists; \
  6. else \
  7. touch file$i; \
  8. echo I made file$i; \
  9. fi; \
  10. done

如果你在上一篇文章使用到的測試目錄中執行以上這串命令,其中的第 3 行會判斷那幾十個檔案當中的某個檔案是否存在。如果檔案存在,會輸出一條提示資訊;如果檔案不存在,就會把對應的檔案創建出來。最終,這個目錄中會完整存在從 file000 到 file099 這一百個檔案。

上面這段命令還可以寫得更加簡潔:

  1. for i in {000..099};\
  2. do\
  3. if [ ! -f file$i ];\
  4. then\
  5. touch file$i;\
  6. echo I made file$i;\
  7. fi;\
  8. done

其中 ! 運運算元表示將判斷結果取反,因此第 3 行的含義就是“如果檔案 file$i 不存在”。

可以嘗試一下將測試目錄中那幾十個檔案隨意刪除幾個,然後執行上面的命令,你就可以看到它是如何把被刪除的檔案重新創建出來的。

除了 -f 之外,還有很多有用的引數。-d 引數可以判斷某個目錄是否存在,-h 引數可以判斷某個檔案是不是一個符號連結。可以用 -G 引數判斷某個檔案是否屬於某個使用者組,用 -ot引數判斷某個檔案的最後更新時間是否早於另一個檔案,甚至還可以判斷某個檔案是否為空檔案。

執行下麵的幾條命令,可以向幾個檔案中寫入一些內容:

  1. echo "Hello World" >> file023
  2. echo "This is a message" >> file065
  3. echo "To humanity" >> file010

然後執行:

  1. for i in {000..099};\
  2. do\
  3. if [ ! -s file$i ];\
  4. then\
  5. rm file$i;\
  6. echo I removed file$i;\
  7. fi;\
  8. done

你就會發現所有空檔案都被刪除了,只剩下少數幾個非空的檔案。

如果你還想瞭解更多別的引數,可以執行 man test 來檢視 test 命令的 man 手冊(test 是 [ ... ] 的命令別名)。

有時候你還會看到 [[ ... ]] 這種雙方括號的形式,使用起來和單方括號差別不大。但雙方括號支援的比較運運算元更加豐富:例如可以使用 == 來判斷某個字串是否符合某個樣式pattern,也可以使用 <> 來判斷兩個字串的出現順序。

可以在 Bash 運算式檔案[3]中瞭解到雙方括號支援的更多運運算元。

下一集

在下一篇文章中,我們會開始介紹圓括號 () 在 Linux 命令列中的用法,敬請關註!

更多

◈ Linux 工具:點的含義[4]
◈ 理解 Bash 中的尖括號[5]
◈ Bash 中尖括號的更多用法[6]
◈ Linux 中的 &[7]
◈ Bash 中的 & 符號和檔案描述符[8]
◈ Bash 中的邏輯和(&)[2]
◈ 淺析 Bash 中的 {花括號}[9]
◈ 在 Bash 中使用[方括號] (一)[1]

已同步到看一看
贊(0)

分享創造快樂