【问题标题】:Alternative for-loop construct替代 for 循环构造
【发布时间】: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 manualBash man-pagesThe 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 提到:

由于历史原因,可以使用左大括号和右大括号代替 dodone,例如

for i; { echo $i; } 

虽然 ZSH 为其他循环构造实现了和 documents 类似的替代方案,但有局限性。它指出:

对于ifwhileuntil 命令,在这两种情况下, 循环的测试部分也必须适当分隔,例如 [[ ... ]](( ... )),否则无法识别测试结束。


问题:这个结构的起源是什么,为什么 这没有传播到其他循环构造?


更新1:下面有一些非常usefuleducational cmets 这篇文章指出这是一个未记录的 Bourne Shell 功能,这似乎是早期 C-vs-sh 语言之争的结果。


更新 2: 当问这个问题时:为什么没有记录此语言功能?Gnu Bash mailinglist,我收到了 Chet Ramey(现任主管)的以下回答-GNU bash 的开发者):

它从未被记录在案。 bash 支持它的原因(未记录)是 因为这是我们实现的未记录的 Bourne shell 功能 为了兼容性。当时,30 多年前,有脚本使用 它。我希望那些剧本已经进入历史的垃圾箱,但是谁 知道现在有多少人在使用这个结构。

我将不记录它;无论如何,人们不应该使用它。


相关问题/答案:


脚注: [1]我没有找到更早的版本,我相信它早于这个

【问题讨论】:

    标签: bash shell sh language-lawyer language-history


    【解决方案1】:

    [W]为什么这不传播到其他循环构造?

    whileuntil 命令的大括号形式在语法上会产生歧义,因为您无法将 test-commandsconsequent- 分开命令之间没有明显的分隔符,因为它们都是defined by POSIX复合lists

    例如,支持此类结构的 shell 可以选择以下命令中的任一括号组作为 consequent-commands,无论哪种方式都是合理的选择。

    while true; { false; }; { break; }
    

    由于其格式不明确,该命令可以翻译为以下任何一种;两者都不是比另一个更准确的翻译,而且他们做的事情完全不同。

    while true; do
        false
    done
    break
    
    while true; { false; }; do
        break
    done
    

    for 命令不受这种歧义的影响,因为它的第一部分是一个变量名,可选地后跟 in 和一个单词列表,或者 @ 的特殊形式987654329@ 复合命令——可以很容易地与构成其第二部分的大括号组区分开来。

    鉴于我们已经为 whileuntil 命令提供了一致的语法,我真的看不出在 传播 这个替代命令中有任何意义形成给他们。

    Wrt 其来源,参见:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-12
      • 1970-01-01
      • 2020-12-22
      • 2012-09-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多