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, zshoryash或外部实用程序,例如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()

相关内容