一段带有大括号的Bash循环?

9

我偶然发现了这个奇怪的问题,但不太明白为什么它能够运行:

$ for ((i=0;i<8;i++)) {
>   printf '%d...' "$i";
> }; echo
0...1...2...3...4...5...6...7...

在bash中使用花括号语法的for循环?我无法使用非算术for循环来复制它,man页和help都似乎需要do
$ help for
<SNIP>
for ((: for (( exp1; exp2; exp3 )); do COMMANDS; done
    Arithmetic for loop.

    Equivalent to
        (( EXP1 ))
        while (( EXP2 )); do
            COMMANDS
            (( EXP3 ))
        done

哦,如果我只是……
$ ((i=0)); while ((i<8)) { printf '%d...' "$i"; ((i++)); }
-bash: syntax error near unexpected token `{'

不行!

这个带括号的 for-loop 语法在哪里有文件记录呢?(官方记录?)

  1. 这是 Bash 中表示算术 for 循环的合法方式吗?
  2. 我是否疏忽了传统的算术 for 循环对输入的解释?

P.S. – 这在 OS X Mavericks 上经过 homebrew 安装的 Bash 4.2.45(2)-release 和自带的 3.2.51(1)-release 的测试。


据我所知,这是Bash中一个大部分未记录的黑科技,可能是为了与同样支持花括号符号的Bourne shell兼容而需要,也没有记录。它不仅适用于Mac OS X,Ubuntu 12.04上也可以这样使用。但似乎不能在while循环或until循环中使用。 - Jonathan Leffler
如果你真的花时间阅读那个回答中发布的文档,而不是轻率地将其下投票,你会发现{ }do done都是命令分组结构。它们通常不能互换,但在循环和if语句的上下文中可以互换。 - Sammitch
@Sammitch 根据POSIX,它明确地不是用于分组命令的结构。如果发布者想要进行调整,我会很高兴地撤销我的反对票并接受给定的答案。 - kojiro
@Sammitch:已删除的答案不准确。do...done 结构不能在可以使用 { ... } 的地方使用; 只能在 forwhileuntil 循环后使用 do...done,而您可以在任何命令可以出现的地方编写 { echo Hi; }(例如 if { echo Hi; }; then echo Lo; fi)。dodone 无法实现这一点。 - Jonathan Leffler
这个问题本身没问题。不幸的是,你对于一个负评没有太多可以做的。如果你遭受了一连串的负评,你可以请求管理员进行调查;或者自动系统也可能会察觉到该问题。 - Jonathan Leffler
显示剩余4条评论
1个回答

9
将一些评论转化为回答:
据我所知,这是Bash中的一个很大程度上未记录的黑客技巧,可能是为了与Bourne shell兼容而需要的,该shell也支持大括号表示法,但同样没有记录。它不是仅适用于Mac OS X;在Ubuntu 12.04上也可以这样使用。然而,在Bash中似乎无法与while循环或until循环一起使用。
“如何在Bourne shell语法中编写算术for循环?”
这是编写for循环体的一种可选方式;在Bourne shell中条件的书写方式会有所不同,但你可以编写类似以下的内容:
for i in 1 2 3
{
    echo $i
}

在Bourne shell中,或者使用do代替{done代替}。我忘记它的存在直到你的问题提醒我;我从未认真使用过它,因为它没有被文档化,因此不能保证支持。 do ... done结构不能用于可以使用{ ... }的地方;您只能在forwhileuntil循环之后使用do ... done,而您可以在任何命令出现的地方编写{ echo Hi; }(例如if { echo Hi; }; then echo Lo; fi)。您无法使用dodone完成这项工作。检查此答案真实性的最佳方法可能是从Heirloom Project下载Heirloom Bourne Shell
我已经下载了Heirloom Bourne Shell的源代码(一个CVS资源库),并进行了构建和测试。它确实接受for循环后面的花括号,但在until或while循环后,不能将其识别为do和done的代用品。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接