我认为下面的行应该以不同的方式编写,并且该命令应该会出错。
$ echo $((x=2, y=3, x+y))
5
Run Code Online (Sandbox Code Playgroud)
我认为写这个的方法是:
$ echo $((x=2, y=3, $x+$y))
5
Run Code Online (Sandbox Code Playgroud)
两者都有效,这现在让我感到困惑。我假设我在某个地方有误解,所以我将解释我如何确定第一个回声是错误的。x+y 没有引用变量,所以 bash 怎么可能知道 x 和 y 是变量。如果你告诉我这是因为表达式开头的 $ ,那么你一定是错的,因为 x 和 y 会被定义在 $x=2 和 $y=2 处,这将是定义变量的不正确方法。所以我完全不知道 bash 如何知道 x 和 y 是变量。
fro*_*utz 15
man bash,ARITHMETIC EVALUATION这样描述它:
\n\n允许 Shell 变量作为操作数;在计算表达式之前\n执行参数扩展。在表达式中,\n也可以通过名称来引用 shell 变量,而不使用参数扩展语法。\n当通过名称而不使用参数扩展语法来\n引用时,空或未设置的 shell 变量的计算结果为 0。当引用变量时,变量的值被计算为算术表达式 [\xe2\x80\xa6]
\n
在 中$(()),它不能是命令、字符串或 shell 通常必须处理的任何其他内容,因此它会扩展变量。它允许赋值,因此您可以分配变量。
然而,实际上你的第二个例子不起作用:
\n$ echo $((x=2, y=3, $x+$y))\nbash: x=2, y=3, +: syntax error: operand expected (error token is "+")\n$ echo $((x=4, y=5, $x+$y))\n5\nRun Code Online (Sandbox Code Playgroud)\n在第一次尝试中,x 和 y 尚未分配。在第二次尝试中,它使用之前分配的值,因此您会得到意外的结果(5 而不是 9)。
\n当您使用 时$,shell 在算术评估发生之前扩展它。因此算术求值中的赋值发生得太晚,无法影响$扩展。
也可以做一些奇怪的事情,例如:
\n$ x=1+2+3\n$ echo $x\n1+2+3\n$ echo $(($x*2))\n9\n$ echo $((x*2))\n12\nRun Code Online (Sandbox Code Playgroud)\n如果您在算术评估之外分配变量,它只是一个字符串。然后您使用$shell 将其扩展为字符串。然后进行算术评估,您必须处理运算符优先级。
因此结果是1+2+3*2 = 9代替6*2 = 12.
$ echo $((x=1+2+3, x*2))\n12\n$ echo $x\n6\nRun Code Online (Sandbox Code Playgroud)\n在此示例中,算术求值发生在赋值之前,因此 x=6 而不是 x=1+2+3。
\n