bash 的算术是如何工作的?

bash 的算术是如何工作的?
 read num1
 2
 read num2
 5
 echo "$((num1+num2))"
 7
 echo "$(($num1+$num2))"
 7

我提到

我不明白上面两个表达式如何产生相同的结果?请解释。

    echo "$[num1+num2]" 

它不按照该问题中的建议工作。我做错了什么吗?

    echo 'expr "$num1" + "$num2"` 

也不工作。请提供一些建议。

答案1

为了计算算术表达式,shell 首先在其中扩展变量和命令替换。例如,在 中echo "$(($num1+$num2))",首先发生的是$num1$num2被变量的值替换。表达式变为2+5.它被解析为算术表达式并计算为数字 7。解析和扩展的结果"$(($num1+$num2))"7

算术表达式可以包含变量名称。这些被评估为变量的值。因此$((num1+num2))是算术表达式num1+num2(而$(($num1+$num2))是算术表达式2+5)。在这种情况下,结果是相同的。

num1当或 的值num2不仅仅是数字序列时,这两个表达式是不同的。例如,考虑以下代码片段:

a="1+2"
echo "$(($a * 4))"
echo "$((a * 4))"

在第二行中,要计算的算术表达式是1+2 * 4。这被解析为 1 + (2 × 4),因为乘法的优先级高于加法。当算术求值发生时,加号来自变量扩展的事实被忘记了。结果是数字 9,因此第一次调用echoprint 9

第三行的行为​​取决于 shell。某些 shell(例如 dash)抱怨a不包含有效的数值。其他 shell(例如 ksh、bash、zsh)将 的值视为a子表达式,对其进行求值以获得要在主表达式中使用的值。也就是说,在这些其他 shell 中, 的值a计算为3,并且算术表达式计算 3 × 4,因此结果为 12。

最后,$[…]是一个已弃用的非标准变体$((…))。该expr实用程序是一种在 shell 脚本中进行算术计算的较旧方法,可以追溯到 shell 没有内置算术语法的时代。expr "$num1" + "$num2"打印 7,冗余也是如此echo `expr "$num1" + "$num2"`(您错误输入了其中一个引号)。

答案2

在 POSIX shell 中,算术扩展有形式:

$((expression))

如果表达式包含变量,并且这些变量包含有效的整数值(前导加号或减号都可以),则"$((var))""$(($var))"将返回相同的结果(注意:在 Shell 算术评估中使用未经处理的数据导致安全隐患)。

表格$[表达式]不是由 POSIX 定义的,已被弃用,并将在下一版本的bash.

表达式实用程序可用于进行算术运算。就您而言,您使用了错误的语法命令替换,它是一个反引号,而不是单引号:

echo `expr "$num1" + "$num2"`

但你应该使用"$()"表单。

相关内容