bash中十進制數的比較

bash中十進制數的比較

今天早上我的搜尋是關於如何在 bash 中比較兩個十進制數,我得到了這個答案:如何在 shell 腳本中與浮點數進行比較。然而,這項一項不包括這個答案在這裡:

$ [[ ((3.56 < 2.90)) ]]; echo $?
1
$ [[ ((3.56 < 4.90)) ]]; echo $?
0

考慮到這個答案已被否決,而且看起來有些不尋常的羞辱,這個算術評估的準確性是否值得信賴?

答案1

bash不懂浮點數。
引用bash手冊頁,部分算術評估:

評估以固定寬度整數完成[...]。

所以((3 < 4))or((3 < 2))其實是正確的算術表達式。您可以輸入以下內容:

$ echo "$((3 < 4)) -- $((3 < 2))"

輸出:1 -- 0

$ echo $((3.3 < 3.6))會回傳語法錯誤訊息。在您的範例中,您實際上是在比較字串。因此有一些例子:

$ [[ ((3.56 < 04.90)) ]]; echo $?

輸出:1

答案2

裡面[[...]] <是用於字串比較的。

所以[[ 3.56 < 2.90 ]]or or [[ (3.56 < 2.90) ]]or [[ ((3.56 < 2.90)) ]]or [[ (((3.56 < 2.90))) ]]... 只是將3.56字串與2.90詞法上的字串進行比較(詞法上,例如3大於)。10

對於整數比較,它是[[ 3 -lt 2 ]]or (( 3 < 2 ))。如果您想要浮點比較,您需要ksh93,zshyash外部實用程序,例如awkor perlbash做不到。

例如,您可以定義一個函數,例如:

compare() (IFS=" "
  exec awk "BEGIN{if (!($*)) exit(1)}"
)

你可以使用它,例如:

if compare '1.5*10 < 1e3'; then
  echo less
fi

或者甚至對這一點來說:

if compare '"bar" < "foo"'...

進行字串比較。

不要將不受控制的外部提供的資料傳遞給該compare函數,因為這會構成命令注入漏洞(資料被解釋為awk程式碼,例如awk可以使用其運行命令)。system()

相關內容