今天早上我的搜索是关于如何在 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
, zsh
oryash
或外部实用程序,例如awk
or 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()