Bash

bash中十進制數的比較

  • May 18, 2018

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

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

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

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

內部[[...]] <用於字元串比較。

所以[[ 3.56 < 2.90 ]]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, zshor或類似oryash的外部實用程序;做不到。awk``perl``bash

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

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())。

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