bash - 替代 for 循环构造
问题描述
一般评论:任何对这个问题提供新的和有用的见解的新答案都将获得奖励。
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]我没有找到更早的版本,我相信它早于这个
解决方案
[W] 为什么这不传播到其他循环结构?
while和until命令的花括号形式在语法上会产生歧义,因为您无法将test-commands与consequent-commands分开,因为它们之间没有独特的分隔符,因为它们都由 POSIX 定义为复合列表。
例如,支持此类结构的 shell 可以选择以下命令中的任一大括号组作为后续命令,无论哪种方式都是合理的选择。
while true; { false; }; { break; }
由于其形式不明确,该命令可以翻译为以下任何一种;两者都不是比另一个更准确的翻译,而且他们做的事情完全不同。
while true; do
false
done
break
while true; { false; }; do
break
done
for命令不受这种歧义的影响,因为它的第一部分——一个变量名可选地后跟一个in和一个单词列表,或者((
复合命令的一种特殊形式——可以很容易地与构成它的第二部分的大括号组区分开来。
鉴于我们已经为while和until命令提供了一致的语法,我真的认为将这种替代形式传播给它们没有任何意义。
Wrt它的起源,见:
推荐阅读
- c# - 将全局筛选应用于从 ASP.NET Entity Framework Core 中的基类继承的所有类
- asp.net-core - 如何在 .NET MAUI Blazor 中删除应用程序图标周围的蓝色框
- c# - 为什么 .NET Core IMemoryCache 分配的内存比需要的多?
- javascript - 嗨,我如何将数字显式转换为数字
- python - 获取任何输入时为真(Python)
- lua - Roblox 错误,“尝试使用 `GetRankInGroup` 索引 nil”
- aws-lambda - 在通过 API 网关公开的无服务器函数中使用 lambda 授权器
- android - 如果手机设备日期设置为未来日期(超过 4 天),Glide 库无法将 url 加载到 imageview
- java - 如何在并行执行中将参数传递给 TestNG 侦听器?
- php - laravel-dompdf 没有显示特殊字符