我正在尝试编写一个可以在任何 POSIX shell 下工作的 shell 脚本,并且我发现了dash
.我想知道这是否是我可以在其他 POSIX 兼容 shell 下工作的依赖,或者它是否只是dash
shell 的一个无意的功能。
在算术扩展中,可以使用或不使用初始美元符号来写入变量(位置参数的情况除外,它必须始终使用美元符号等写入$1
)$2
。
但我发现 的行为与似乎扩展的行为"$((X))"
不同"$(($X))"
"$(($X))"
两次,而不仅仅是一次。即如果我的变量X
包含另一个变量的名称( X=Y
),它又包含一个数值 ( Y=1
) 然后"$(($X))"
将返回1
,而"$((X))"
只会产生“非法数字:Y”错误。
我可以相信这种行为在其他 POSIX shell 中是相同的吗?
奇怪的行为
"$((X))"
并且"$(($X))"
行为不一样。
$ X=Y; Y=1
$ echo "$((X))"
dash: 1: Illegal number: Y
$ echo "$(($X))"
1
预期行为
为了完整起见,我在这里包括了没有间接和两层间接的内容。没有间接性,一切都按预期工作:
$ X=1
$ echo "$((X))"
1
$ echo "$(($X))"
1
正如预期的那样,两层间接不起作用(尽管请注意错误消息引用了不同的值)。
$ X=Y; Y=Z; Z=1
$ echo "$((X))"
dash: 6: Illegal number: Y
$ echo "$(($X))"
dash: 7: Illegal number: Z
这个问题与这个问题有些相关算术展开和参数展开但它不一样,因为它处理bash
更高级 shell 的行为,但我想知道预期的 POSIX 行为。
答案1
由于您的问题是 POSIX-generic,并且相关问题似乎涉及更高级的 shell,因此我将单独回答这个问题。
您看到的行为来自两种不同的扩展,参数扩展和算术扩展,POSIX 按该顺序指定。和
$ X=Y; Y=1
您的第一个示例仅使用算术扩展:
$ echo "$((X))"
尝试将 的值解释X
为算术表达式,但失败了,因为“Y”不是数字。
您的第二个示例同时使用:
$ echo "$(($X))"
被扩展(参数扩展)为
$ echo "((Y))"
然后算术展开使用Y
的值 1。