Bash

[[測試中的字元串與整數比較

  • December 19, 2018

我在這裡查看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

有關此問題的更多資訊,請參閱此答案

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