我有一个关于 bash 的参数扩展的问题,在逗号表达式中,在算术表达式中。我有两个我认为应该等价的陈述,但事实并非如此。
为什么 bash 行
n=3; k=10; echo $((n++,k=$n))
输出3
而不是4
?(正如我所料,它设置n
为4
,但设置k
为3
。)
相比之下,bash 行
n=3; k=10; echo $((n++,k=n))
输出4
,正如我所料。(它设置n
为4
,也设置k
为4
。)
我尝试在两个 bash 行中替换n++
with ++n
、 withn=n+1
和 with ,它们都产生n=$((n+1))
相同的差异:所有脚本中的yield 和所有脚本中的yield 。k=$n
3
k=n
4
我的理解是,如果 的值n
是一个整数(它是),$n
并且n
在算术表达式中应该具有相同的值。(由于结构,这是一个算术表达式(( ... ))
。)根据 bash 手册,在算术评估部分,在算术表达式中:
Shell variables are allowed as operands; parameter expansion is performed before the
expression is evaluated. Within an expression, shell variables may also be referenced by
name without using the parameter expansion syntax.
那么,为什么 bash 的处理$n
方式与n
此示例中的不同,它究竟是如何评估的$n
呢?
如果不使用逗号运算符,我无法复制该问题。逗号运算符,从我经常看到的,从左到右计算它的每个组件子表达式,包括计算该组件时每个组件的所有副作用。逗号表达式的值就是计算的最后一个分量的值(最右边的那个)。
这个问题是在一个更复杂的脚本的上下文中出现的,我最终将其缩小到这个简单的例子来演示这个问题。
那么,我对算术扩展、参数扩展或逗号运算符有什么误解?
请注意,我不是在寻找解决方法,因为我已经有了一个:带有n
代替的版本$n
按我的预期工作。我只是想了解 bash 在带有 . 的版本中做了什么$n
,以及为什么它与带有n
.
Shell 参数扩展发生在计算表达式之前,包括逗号处理:
你可以看到这个
错误信息,
显示
$n
在处理整个算术表达式之前被替换。在您的情况下,评估的表达式是
在内部
$((...))
,首先进行扩展¹,就像使用双引号一样,然后评估结果。所以在
n=3; k=10; echo $((n++,k=$n))
(或n=1; echo "$((++n + $n))"
,不限于,
)中,计算的算术表达式是n++, k=3
。在这里,您需要:
(还要注意引号,因为算术扩展像 POSIX shell 中的其他形式的单词扩展一样受到 split+glob 的影响)。
¹,您会发现调用数组和关联数组的一些变化,因为某些 shell 会尝试
$((hash[$key]++))
正确处理$key
包含]
例如