且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

为什么bash brace扩展在某些算术表达式中起作用而在其他算术表达式中却不起作用?

更新时间:2023-02-10 19:11:58

设置1990年的退回机器方式.

Setting the way back machine for 1990.

Bash根据POSIX P1003.2d9(大约在1990年)实现了 $ [] 语法,这是已发布的P1003.2-1992的草案.在草稿和标准之间的两年中,POSIX决定使用ksh88 $(())语法和行为.Chet Ramey(bash维护者)这样说,返回2012 :

Bash implemented the $[] syntax per POSIX P1003.2d9 (circa 1990), which was a draft of the released P1003.2-1992. In the two years between draft and standard, POSIX had instead settled on the ksh88 $(()) syntax and behaviors. Chet Ramey (bash maintainer) had this to say, back in 2012:

Bash ...实现了$ [...],因为没有其他选项当时的语法,并获得一些操作经验外壳中的算术扩展.Bash-1.14 ...列出了两种形式的算术扩展,但是通过当bash-2.0于1995年发布时,该手册仅涉及$((...))表格.

Bash... implemented $[...] because there was no other syntax at the time, and to gain some operational experience with arithmetic expansion in the shell. Bash-1.14... lists both forms of arithmetic expansion, but by the time bash-2.0 was released in 1995, the manual referred only to the $((...)) form.

这向我表明, $ [] 形式是实验性,并且它具有某些行为(例如括号扩展),当POSIX采用 $(())语法.这些实验行为被遗忘了,因为野外已经有脚本依赖它们了(记住已经过去了两年多.)

This suggests to me that the $[] form was experimental, and it had certain behaviors (like brace expansion) that were specified into oblivion when POSIX adopted the $(()) syntax. Those experimental behaviors were left in, since there were already scripts in the wild relying on them (remember more than 2 years had elapsed).

Chet在同一线程中清楚地表明 $ [] 形式已过时,但尚未弃用:

Chet makes clear in that same thread that the $[] form is obsolete, but not deprecated:

现在,继续拖动$ [...]语法几乎没有问题.它只需要几十个字节的代码.我没有删除它的计划.

Now, it's hardly any problem to keep dragging the $[...] syntax along. It takes only a few dozen bytes of code. I have no plans to remove it.

当前的POSIX标准,C.2.6单词扩展>算术扩展提到语法(重点是我的):

The current POSIX standard, C.2.6 Word Expansions > Arithmetic Expansion mentions the syntax (emphasis mine):

在早期建议中,使用$ [expression]形式.它在功能上等同于当前文本的"$(())" ,但是有人提出反对意见,认为1988年的KornShell已经实现了"$(())",并且没有令人信服的理由发明另一种语法.此外,"$ []"语法与case语句中的模式存在较小的不兼容性.

In early proposals, a form $[expression] was used. It was functionally equivalent to the "$(())" of the current text, but objections were lodged that the 1988 KornShell had already implemented "$(())" and there was no compelling reason to invent yet another syntax. Furthermore, the "$[]" syntax had a minor incompatibility involving the patterns in case statements.

因此,bash中实现的行为并不完全符合规范,但是由于没有计划将其删除,因此,如果它能巧妙地解决您的问题,我认为没有理由放弃它的好处.但是,正如@Barmar的评论所指出的那样,对代码进行注释并在此处链接是一个好主意,以便将来的开发人员知道您的意思!

So the as-implemented behavior in bash isn't quite to specification, but since there are no plans to remove it, I see no reason to forgo its benefits if it neatly solves your problem. However, as pointed out by @Barmar's comment, it'd be A Good Idea to comment the code and link it here so future developers know what the heck you mean!