【发布时间】:2020-11-24 13:59:58
【问题描述】:
一般性评论:任何对这个问题提供新的有用见解的新答案都将获得奖励。
Bash reference manual 提到 Bash 支持 以下 for 循环结构:
for name [ [in [words ...] ] ; ] do commands; done
for (( expr1 ; expr2 ; expr3 )) ; do commands ; done
令人惊讶的是,以下 for 循环结构也是有效的:
for i in 1 2 3; { echo $i; }
for ((i=1;i<=3;++i)); { echo $i; }
根本没有记录这些不寻常的构造。 Bash manual、Bash man-pages 和 The Linux Documentation Project 均未提及这些构造。
在调查language grammar 时,可以看到使用
开闭大括号 ({ commands; }) 作为do commands; done 的替代品是一个有效的结构,它对两者都实现了
for-loops 和 select 语句可以追溯到Bash-1.14.7
[1].
另外两个循环结构:
until test-commands; do consequent-commands; done
while test-commands; do consequent-commands; done
没有这种替代形式。
由于很多shell语言都是相关的,可以发现这些 那里也定义了结构,并温和地记录在案。 KSH manual 提到:
由于历史原因,可以使用左大括号和右大括号代替
do和done,例如for i; { echo $i; }
虽然 ZSH 为其他循环构造实现了和 documents 类似的替代方案,但有局限性。它指出:
对于
if、while和until命令,在这两种情况下, 循环的测试部分也必须适当分隔,例如[[ ... ]]或(( ... )),否则无法识别测试结束。
问题:这个结构的起源是什么,为什么 这没有传播到其他循环构造?
更新1:下面有一些非常useful和educational cmets 这篇文章指出这是一个未记录的 Bourne Shell 功能,这似乎是早期 C-vs-sh 语言之争的结果。
更新 2: 当问这个问题时:为什么没有记录此语言功能?Gnu Bash mailinglist,我收到了 Chet Ramey(现任主管)的以下回答-GNU bash 的开发者):
它从未被记录在案。 bash 支持它的原因(未记录)是 因为这是我们实现的未记录的 Bourne shell 功能 为了兼容性。当时,30 多年前,有脚本使用 它。我希望那些剧本已经进入历史的垃圾箱,但是谁 知道现在有多少人在使用这个结构。
我将不记录它;无论如何,人们不应该使用它。
相关问题/答案:
- A bash loop with braces?
- Hidden features of Bash (this answer)
- [U&L] What is the purpose of the “do” keyword in Bash for loops?
脚注: [1]我没有找到更早的版本,我相信它早于这个
【问题讨论】:
标签: bash shell sh language-lawyer language-history