今朝の私の検索は、bashで2つの10進数を比較する方法についてでした。私はこの答えに行きました: シェルスクリプトで浮動小数点数と比較する方法 。ただし、これには この回答は含まれていません :
$ [[ ((3.56 < 2.90)) ]]; echo $?
1
$ [[ ((3.56 < 4.90)) ]]; echo $?
0
その回答が反対投票されており、ある種の異常なバシズムに見えることを考えると、この算術評価は正確性について信頼できるのでしょうか?
bash
は浮動小数点数を認識しません。
引用bash
マニュアルページ、セクションARITHMETIC EVALUATION:
評価は固定幅整数[…]で行われます。
したがって、_((3 < 4))
_または_((3 < 2))
_は実際には正しい算術式です。次のように入力できます。
_$ echo "$((3 < 4)) -- $((3 < 2))"
_
出力:_
1 -- 0
_
ただし、$ echo $((3.3 < 3.6))
は構文エラーメッセージを返します。あなたの例では、実際には文字列を比較しています。したがって、いくつかの例:
_$ [[ ((3.56 < 04.90)) ]]; echo $?
_
出力:_
1
_
_[[...]]
_の内部_<
_は文字列比較用です。
つまり、_[[ 3.56 < 2.90 ]]
_または[[ (3.56 < 2.90) ]]
または[[ ((3.56 < 2.90)) ]]
または[[ (((3.56 < 2.90))) ]]
...は、_3.56
_文字列を_2.90
_文字列と字句的に比較しているだけです(そして、字句的には、_3
_は_10
_よりも大きいです)。
整数比較の場合、これは_[[ 3 -lt 2 ]]
_または_(( 3 < 2 ))
_です。浮動小数点比較が必要な場合は、_ksh93
_、zsh
またはyash
または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()
など)。