所有 POSIX shell 都以相同的方式实现算术扩展 $((...)) 吗?

所有 POSIX shell 都以相同的方式实现算术扩展 $((...)) 吗?

我正在尝试编写一个可以在任何 POSIX shell 下工作的 shell 脚本,并且我发现了dash.我想知道这是否是我可以在其他 POSIX 兼容 shell 下工作的依赖,或者它是否只是dashshell 的一个无意的功能。

在算术扩展中,可以使用或不使用初始美元符号来写入变量(位置参数的情况除外,它必须始终使用美元符号等写入$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。

也可以看看了解在算术表达式中使用间接扩展进行变量扩展的两个示例Bash:算术扩展、参数扩展和逗号运算符等。

相关内容