Bash
bash中十進制數的比較
我今天早上的搜尋是關於如何在 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
,zsh
or或類似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()
)。