算术展开和参数展开

算术展开和参数展开
$ x=foo; foo=bar; bar=6; 

$ echo $x
foo

$ echo $((x))
6

为什么算术展开式可以从变量追踪x到它的值foo,从变量foo追踪到它的值bar,然后从变量追踪foo到它的值,而不是停在的6值上?foox

看起来算术扩展是否eval 无限多次地应用于变量的参数扩展x,直到达到整数或什么都没有?

答案1

bash这是(以及及其衍生物)的扩展,zsh允许kshshell 变量包含在算术表达式中重用的无效整数常量。

来自bash壳算术:

允许 Shell 变量作为操作数;参数扩展在表达式求值之前执行。在表达式中,shell 变量也可以通过名称引用,而不使用参数扩展语法。当通过名称引用而不使用参数扩展语法时,为 null 或未设置的 shell 变量的计算结果为 0。当引用变量时,或者当为使用“declare -i”赋予整数属性的变量赋值时,变量的值将被计算为算术表达式。 null 值的计算结果为 0。shell 变量无需打开其整数属性即可在表达式中使用。

因此,在您的情况下,$((x))首先扩展xfoo,这是一个无效整数,因此foo被重用为变量名引用。然后foo展开为bar,重复上述过程,直到得到6,这是一个有效的整数。


POSIX 规范仅规定$((x))和仅当是有效整数常量$(($x))时才会返回相同的值。x它没有说明任何关于x无效整数的情况,因此 shell 实现可以自由地处理这种情况。

不同的 shell 结果可能会有所不同。

zshksh及其衍生品的行为类似于bash上面(以及 busybox sh)。

ash,如果包含无效整数dash则引发错误x

$ x=foo foo=bar bar=6 dash -c 'echo "$((x))"'
dash: 1: Illegal number: foo

yash将变量保留原样:

$ x=foo foo=bar bar=6 yash -c 'echo "$((x))"'
foo

相关内容