算术扩展如何处理没有 $(美元)符号的变量?

算术扩展如何处理没有 $(美元)符号的变量?

我认为下面的行应该以不同的方式编写,并且该命令应该会出错。

$ echo $((x=2, y=3, x+y))
5

我认为写这个的方法是:

$ echo $((x=2, y=3, $x+$y))
5

两者都有效,这现在让我感到困惑。我假设我在某个地方有误解,所以我将解释我如何确定第一个回声是错误的。 x+y 没有引用变量,所以 bash 怎么可能知道 x 和 y 是变量。如果你告诉我这是因为表达式开头的 $ ,那么你一定是错的,因为 x 和 y 会被定义在 $x=2 和 $y=2 处,这将是定义变量的不正确方法。所以我完全不知道 bash 如何知道 x 和 y 是变量。

答案1

man bashARITHMETIC EVALUATION这样描述它:

允许 Shell 变量作为操作数;参数扩展在计算表达式之前执行。在表达式中,shell 变量也可以通过名称引用,而不使用参数扩展语法。当通过名称引用而不使用参数扩展语法时,为 null 或未设置的 shell 变量的计算结果为 0。当引用变量时,变量的值将被计算为算术表达式 [...]

在 中$(()),它不能是命令、字符串或 shell 通常必须处理的任何其他内容,因此它会扩展变量。它允许赋值,因此您可以分配变量。

然而,实际上你的第二个例子不起作用:

$ echo $((x=2, y=3, $x+$y))
bash: x=2, y=3, +: syntax error: operand expected (error token is "+")
$ echo $((x=4, y=5, $x+$y))
5

在第一次尝试中,x 和 y 尚未分配。在第二次尝试中,它使用之前分配的值,因此您会得到意外的结果(5 而不是 9)。

当您使用 时$,shell 在算术评估发生之前扩展它。因此算术求值中的赋值发生得太晚,无法影响$扩展。

也可以做一些奇怪的事情,例如:

$ x=1+2+3
$ echo $x
1+2+3
$ echo $(($x*2))
9
$ echo $((x*2))
12

如果您在算术评估之外分配变量,它只是一个字符串。然后您使用$shell 将其扩展为字符串。然后进行算术评估,您必须处理运算符优先级。

因此结果是1+2+3*2 = 9代替6*2 = 12.

$ echo $((x=1+2+3, x*2))
12
$ echo $x
6

在此示例中,算术求值发生在赋值之前,因此 x=6 而不是 x=1+2+3。

相关内容