Bash
[[測試中的字元串與整數比較
我在這裡查看Kusalananda 和 xhienne 之間的討論,其中提到它
[ "" -ge 2 ]
不是一個有效的測試,會在bash --posix
其他符合 POSIX 的 shell 中產生錯誤。bash-4.3$ [ "" -gt 10 ] bash: [: : integer expression expected bash-4.3$ [ '' -gt 10 ] bash: [: : integer expression expected
那裡一切都好。出於好奇,我對
[[
.bash-4.3$ [[ "" -gt 10 ]] && echo "YES" bash-4.3$ [[ "" -gt 0 ]] && echo "YES" bash-4.3$ [[ "" -gt -1 ]] && echo "YES" YES bash-4.3$ [[ "" -eq 0 ]] && echo "YES" YES
如您所見,沒有錯誤,它實際上被評估為“”等於0的數字表達式。那麼這裡到底發生了什麼?只是
[[
與舊的test
或 POSIX 不一致嗎?它只是執行字元串比較而不是數字比較嗎?
[
和之間的一個區別[[
是它[
不進行算術評估,而是[[
:$ [ "2 + 2" -eq 4 ] && echo yes bash: [: 2 + 2: integer expression expected $ [[ "2 + 2" -eq 4 ]] && echo yes yes
第二個微妙之處是,無論在 bash 下執行算術評估的任何地方,空字元串都會評估為 0。例如:
$ x=""; echo $((0 + x)) 0 $ [[ "" -eq 0 ]] && echo yes yes
文件
來自
man bash
:允許 shell 變數作為操作數;在計算表達式之前執行參數擴展。在表達式中,shell 變數也可以通過名稱來引用,而無需使用參數擴展語法。當不使用參數擴展語法按名稱引用時,為 null 或未設置的 shell 變數的計算結果為 0。變數的值在被引用時被評估為算術表達式,或者當使用 declare -i 賦予了整數屬性的變數被賦值時。 空值的計算結果為 0。shell 變數不需要打開其整數屬性才能在表達式中使用。[強調補充]
旁白:安全問題
請注意,bash 的算術評估是一個潛在的安全問題。例如,考慮:
x='a[$(rm -i *)]' [[ x -eq 0 ]] && echo yes
使用該
-i
選項,上述內容是安全的,但一般的教訓是不要將 bash 的算術評估與未清理的數據一起使用。相比之下,
[
不執行算術評估,因此該命令從不嘗試刪除文件。相反,它會安全地生成錯誤:$ x='a[$(rm -i *)]' $ [ "$x" -eq 0 ] && echo yes bash: [: a[$(rm -i *)]: integer expression expected
有關此問題的更多資訊,請參閱此答案。