Jak*_*kub 4 bash shell arithmetic-expressions brace-expansion
我正在编写一个非常简单的 bash 脚本,但我无法理解为什么已弃用的 $[] 可以完美地工作,而 $(()) 似乎破坏了整个事情。
我所指的代码是:
for i in {1..10};
do
printf %4d $[{1..10}*i]
echo
done
Run Code Online (Sandbox Code Playgroud)
在此版本中,我没有遇到任何问题,但我不想使用已弃用的 bash 元素,这就是我想切换到 $(()) 的原因。
不幸的是,一旦我将代码更改为:
printf %4d $(({1..10}*i))
Run Code Online (Sandbox Code Playgroud)
我收到一个错误:
./script_bash.sh: line 8: {1..10}*i: syntax error: argument expected (error token is "{1..10}*i")
Run Code Online (Sandbox Code Playgroud)
我会很感激在这方面提供一些帮助......
将机器设置为 1990 年。
Bash$[]按照 POSIX P1003.2d9(大约 1990 年)实现了语法,该语法是已发布的 P1003.2-1992 的草案。在草案和标准之间的两年时间里,POSIX 转而采用了 ksh88$(())语法和行为。Chet Ramey(bash 维护者)早在 2012 年就说过这样的话:
Bash...实现了 $[...] 因为当时没有其他语法,并且为了在 shell 中获得一些算术扩展的操作经验。Bash-1.14... 列出了算术展开的两种形式,但到 1995 年 bash-2.0 发布时,手册仅提到 $((...)) 形式。
这对我来说表明该$[]形式是实验性的,并且它具有某些行为(例如大括号扩展),当 POSIX 采用该语法时,这些行为被指定为遗忘$(())。这些实验行为被保留下来,因为已经有依赖它们的脚本(记住已经过去了两年多)。
Chet 在同一线程中明确表示该$[]形式已过时,但并未弃用:
现在,继续使用 $[...] 语法几乎没有任何问题。只需要几十个字节的代码。我没有删除它的计划。
当前的 POSIX标准C.2.6 Word Expansions > Arithmetic Expansion提到了语法(重点是我的):
在早期的提案中,使用了 $[表达式] 形式。它在功能上等同于当前文本的“$(())”,但有人提出反对意见,认为 1988 年的 KornShell 已经实现了“$(())”,并且没有令人信服的理由发明另一种语法。此外,“$[]”语法在涉及 case 语句中的模式时存在轻微的不兼容性。
因此,bash 中实现的行为并不完全符合规范,但由于没有计划删除它,如果它能巧妙地解决您的问题,我认为没有理由放弃它的好处。然而,正如 @Barmar 的评论所指出的,评论代码并将其链接到此处是一个好主意,这样未来的开发人员就知道你到底是什么意思!