我认为下面的行应该以不同的方式编写,并且该命令应该会出错。
$ 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 bash
,ARITHMETIC 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。