一般评论:任何对这个问题提供新的和有用的见解的新答案都将获得奖励。
Bash 参考手册提到 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 手册、Bash 手册页和Linux 文档项目都没有提及这些结构。
在研究语言语法时,可以看到使用开闭大括号 ( { commands; }
) 作为替代方案do commands; done
是一种有效的构造,它适用于 for 循环和 select 语句,并且可以追溯到Bash-1.14.7
[1]。
另外两个循环结构:
until test-commands; do consequent-commands; done
while test-commands; do consequent-commands; done
没有这种替代形式。
由于许多 shell 语言是相关的,人们可以发现这些结构也在那里定义并温和地记录在案。KSH 手册提到:
由于历史原因,可以使用开括号和闭括号代替
do
and,done
例如for i; { echo $i; }
而 ZSH 为其他循环结构实现并记录了类似的替代方案,但有局限性。它指出:
对于
if
,while
和until
命令,在这两种情况下,循环的测试部分也必须适当分隔,例如用[[ ... ]]
or(( ... ))
,否则将无法识别测试的结束。
问题:这个构造的起源是什么,为什么它没有传播到其他循环构造?
更新 1:在这篇文章下面有一些非常有用和有教育意义的评论指出这是一个未记录的 Bourne Shell 功能,这似乎是早期 C-vs-sh 语言战斗的结果。
更新 2:问问题时:为什么没有记录此语言功能?在Gnu Bash 邮件列表中,我收到了 Chet Ramey(GNU bash 的现任首席开发人员)的以下答复:
它从未被记录在案。bash 支持它的原因(未记录)是因为它是一个未记录的 Bourne shell 功能,我们为了兼容性而实现了它。当时,30 多年前,有使用它的脚本。我希望那些脚本已经进入历史的垃圾箱,但谁知道现在有多少人在使用这个结构。
我将不记录它;人们无论如何都不应该使用它。
相关问题/答案:
脚注: [1]我没有找到更早的版本,我相信它早于这个