替代 for 循环结构
Alternative for-loop construct
一般评论:任何对这个问题提供新的有用见解的新答案都将获得奖励。
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
手册、Bash man-pages 或Linux 文档
Project 提及这些结构。
调查 language grammar 时可以看到使用
打开和关闭大括号 ({ 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 manual 提到:
For historical reasons, open and close braces may be used instead of do
and done
e.g.
for i; { echo $i; }
而 ZSH 为其他循环构造实现了和 documents 类似的替代方案,但有限制。它指出:
For the if
, while
and until
commands, in both these cases the
test part of the loop must also be suitably delimited, such as by
[[ ... ]]
or (( ... ))
, else the end of the test will not be recognized.
问题:这个构造的起源是什么,为什么是
这没有传播到其他循环结构?
更新 1: 下面有一些非常 and 的评论
这个 post 指出这是一个未记录的 Bourne Shell 功能,这似乎是早期 C-vs-sh 语言斗争的结果。
更新 2: 当问这个问题时:为什么这个语言特性没有记录? 到 Gnu Bash mailinglist,我从 Chet Ramey(GNU bash 的现任首席开发人员)那里收到了以下答复:
It's never been documented. The reason bash supports it (undocumented) is
because it was an undocumented Bourne shell feature that we implemented
for compatibility. At the time, 30+ years ago, there were scripts that used
it. I hope those scripts have gone into the dustbin of history, but who
knows how many are using this construct now.
I'm going to leave it undocumented; people should not be using it anyway.
相关questions/answers:
- 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] 我没有找到更早的版本,我相信它早于这个
[W]hy is this not propagated to the other loop-constructs?
while 和 until 命令的大括号形式在句法上会产生歧义,因为您无法将 [=61 分开=] 来自 consequent-commands,它们之间没有明显的分隔符,因为它们都是 defined by POSIX to be compound lists.
例如,支持此类构造的 shell 可以在下面的命令中选择任何一个大括号组作为 consequent-commands 并且无论哪种方式将是一个合理的选择。
while true; { false; }; { break; }
由于其模棱两可的形式,该命令可以翻译成以下任一形式;没有一个翻译比另一个更准确,而且它们做的事情完全不同。
while true; do
false
done
break
while true; { false; }; do
break
done
for 命令不受这种歧义的影响,因为它的第一部分是一个变量名,后跟 in 和一个单词列表, 或 ((
复合命令的特殊形式——可以很容易地与构成其第二部分的大括号组区分开来。
鉴于我们已经对 while 和 until 命令有了一致的语法,我真的看不出 向他们传播这种替代形式。
关于它的起源,见:
一般评论:任何对这个问题提供新的有用见解的新答案都将获得奖励。
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 手册、Bash man-pages 或Linux 文档 Project 提及这些结构。
调查 language grammar 时可以看到使用
打开和关闭大括号 ({ 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 manual 提到:
For historical reasons, open and close braces may be used instead of
do
anddone
e.g.for i; { echo $i; }
而 ZSH 为其他循环构造实现了和 documents 类似的替代方案,但有限制。它指出:
For the
if
,while
anduntil
commands, in both these cases the test part of the loop must also be suitably delimited, such as by[[ ... ]]
or(( ... ))
, else the end of the test will not be recognized.
问题:这个构造的起源是什么,为什么是 这没有传播到其他循环结构?
更新 1: 下面有一些非常
更新 2: 当问这个问题时:为什么这个语言特性没有记录? 到 Gnu Bash mailinglist,我从 Chet Ramey(GNU bash 的现任首席开发人员)那里收到了以下答复:
It's never been documented. The reason bash supports it (undocumented) is because it was an undocumented Bourne shell feature that we implemented for compatibility. At the time, 30+ years ago, there were scripts that used it. I hope those scripts have gone into the dustbin of history, but who knows how many are using this construct now.
I'm going to leave it undocumented; people should not be using it anyway.
相关questions/answers:
- 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] 我没有找到更早的版本,我相信它早于这个
[W]hy is this not propagated to the other loop-constructs?
while 和 until 命令的大括号形式在句法上会产生歧义,因为您无法将 [=61 分开=] 来自 consequent-commands,它们之间没有明显的分隔符,因为它们都是 defined by POSIX to be compound lists.
例如,支持此类构造的 shell 可以在下面的命令中选择任何一个大括号组作为 consequent-commands 并且无论哪种方式将是一个合理的选择。
while true; { false; }; { break; }
由于其模棱两可的形式,该命令可以翻译成以下任一形式;没有一个翻译比另一个更准确,而且它们做的事情完全不同。
while true; do
false
done
break
while true; { false; }; do
break
done
for 命令不受这种歧义的影响,因为它的第一部分是一个变量名,后跟 in 和一个单词列表, 或 ((
复合命令的特殊形式——可以很容易地与构成其第二部分的大括号组区分开来。
鉴于我们已经对 while 和 until 命令有了一致的语法,我真的看不出 向他们传播这种替代形式。
关于它的起源,见: