
我知道我能做到
$ [ -w /home/durrantm ] && echo "writable"
writable
或者
$ test -w /home/durrantm && echo "writable"
writable
或者
$ [[ -w /home/durrantm ]] && echo "writable"
writable
我喜歡使用第三種文法。它們在所有方面以及所有負面和邊緣情況下都是等價的嗎?可攜性是否有任何差異,例如 Ubuntu 上的 bash 和 OS X 或舊/新 bash 版本(例如 4.0 之前/之後)之間的差異,它們是否都以相同的方式擴展表達式?
答案1
是的,存在差異。最便攜的是test
或[ ]
。這些都是POSIXtest
規範。
構造if ... fi
也是由 POSIX 定義並且應該是完全便攜的。
該[[ ]]
功能ksh
也存在於某些版本中bash
(所有現代的),在其他 shell 中zsh
,也許在其他 shell 中,但不存在於sh
或dash
或其他各種較簡單的 shell 中。
因此,為了使您的腳本可移植,請使用[ ]
,test
或if ... fi
.
答案2
[
是命令的同義詞test
,同時也是bash 內建和單獨的命令。但是[[
是一個bash 關鍵字並且僅適用於某些版本。因此,出於可移植性的原因,您最好使用單一[]
或test
[ -w "/home/durrantm" ] && echo "writable"
答案3
請注意,這與建築[] && cmd
不同。if .. fi
有時它的行為非常相似,您可以[] && cmd
使用if .. fi
.但只是有時。如果您有多個命令要執行 if 條件,或者您需要if .. else .. fi
小心並了解其邏輯。
舉幾個例子:
[ -z "$VAR" ] && ls file || echo wiiii
不一樣
if [ -z $VAR ] ; then
ls file
else
echo wiii
fi
因為 ifls
會失敗,echo
將會被執行,而 . 不會發生這種情況if
。
另一個例子:
[ -z "$VAR" ] && ls file && echo wiii
不等於
if [ -z "$VAR" ] ; then
ls file
echo $wiii
fi
雖然這個結構的作用是一樣的
[ -z "$VAR" ] && { ls file ; echo wiii ; }
請注意;
echo 很重要且必須存在。
所以繼續上面的陳述我們可以說
[] && cmd
== 如果第一個指令成功則執行下一個指令
if .. fi
== if 條件(也可能是測試指令)然後執行指令
因此僅用於之間的移植[
和[[
使用[
。
if
與 POSIX 相容。因此,如果您必須在兩者之間做出選擇[
,if
請考慮您的任務和預期行為。
答案4
為了便於移植,請使用test
/ [
。但是,如果您不需要可移植性,為了您自己和其他人閱讀您的腳本的理智,請使用[[
. :)
另請What is the difference between test, [ and [[ ?
參見Bash常見問題解答。