Bash

[ vs [[ :在 bash 腳本中使用哪一個?

  • September 1, 2021

zsh 手冊頁的test(aka [) 部分明確建議不要使用它,並敦促讀者盡可能使用[[

相關部分指出:

該命令嘗試實現 POSIX 及其指定的擴展。不幸的是,語法中存在固有的歧義。特別是測試運算符和類似它們的字元串之間沒有區別。該標準試圖為少量參數(最多四個)解決這些問題;不能依賴五個或更多參數的兼容性。敦促使用者盡可能使用[[沒有這些歧義的 ’ ’ 測試語法。

我想我遇到過關於 bash 的類似建議,但是當我瀏覽 bash 手冊頁時,我找不到任何關於使用哪種形式 ([[[) 的“官方”建議。(也許我錯過了?)

除了向後兼容“舊外殼”之外,還有什麼理由可以[在 bash 腳本中使用?或者換一種說法,bash是否因為向後兼容性以外的原因而保持[一致?[[

如果足夠的話,首選的原因[是不同的 bash 版本之間更穩定。[[``[

man bash

兼容31

如果設置,bash 將其行為更改為 3.1 版的行為,以引用 [[ 條件命令的 =~ 運算符的參數。

兼容32

如果設置,則 bash 在使用 [[ 條件命令的 < 和 > 運算符時,將其行為更改為 3.2 版的行為,以進行特定於語言環境的字元串比較。bash-4.1 之前的 Bash 版本使用 ASCII 排序規則和 strcmp(3);bash-4.1 和更高版本使用目前語言環境的排序規則和 strcoll(3)。

兼容40

如果設置,則 bash 在使用 [[ 條件命令的 < 和 > 運算符(請參閱上一項)和中斷命令列表的效果時,將其行為更改為 4.0 版的行為,以進行特定於語言環境的字元串比較。

ksh也許對於有背景的使用者來說也更常見一些。

性能注意事項

‘[[’ 比 ‘[’ 更快

  • 對於單個呼叫,速度差異沒有可比的影響,您應該更喜歡 ‘[’ 內置。
  • 如果你在一個更大的循環結構中,你可能會想到用 ‘[[’ 替換 ‘[’

對於測量,您可以使用以下比較腳本

let upperBound=$1
echo "check [,  ${upperBound} iterations"
let i=0
time while [ $i -lt ${upperBound} ] ; do let i++ ; done

echo; echo;
echo "check [[, ${upperBound} iterations"
let i=0
time while [[ $i &lt; ${upperBound} ]] ; do let i++ ; done

比較腳本的結果

檢查 [, 1000 次迭代

真實 0m0.031s

使用者 0m0.028s

系統 0m0.004s

檢查 [[, 1000 次迭代

實際 0m0.000s

使用者 0m0.000s

系統 0m0.000s

雖然有一些細微的差別:

#!/bin/bash

eg=whatever

if [ $eg == what* ]; then   # file glob test
   echo '[]'
fi

if [[ $eg == what* ]]; then   # pattern match test
   echo "[[]]"
fi      

除非目前目錄中有一個名為“whatever”的文件,否則第一個測試不會通過,因為匹配是針對目前目錄內容的文件 glob,而第二個是實際的字元串模式匹配。

引用自:https://unix.stackexchange.com/questions/67172