为什么在这些情况下不需要分号?

Yoo*_* N. 4 bash shell

这个问题的答案让我感到困惑."他们都错了!" 是我的想法,因为我之前在与OP相同或类似的情况下省略了分号,并且一切正常.

有关复合命令的文档似乎证明这些答案是正确的:

{ list; }

以下列表中的分号(或换行符)是必需的.

...它说的是关于分组命令,以及类似的循环:

注意,无论哪里';' 出现在命令语法的描述中,它可以替换为一个或多个换行符.

...并且所有示例都使用分号.

但是,在实践中,你可以在嵌套循环时自由省略分号,如果,花括号等,以任何顺序.例如:

{ if true; then echo; fi }
# no ";" here           ^
for i in {1..3}; do if true; then echo "$i"; fi done
# no ";" here                                  ^
{ while true; do if true; then for i in {1..3}; do { echo "$i"; } done fi done }
# no ";" in these 4 places                                       ^    ^  ^    ^
Run Code Online (Sandbox Code Playgroud)

我已经在bash 4.1,4.2,4.4和破折号0.5.7上进行了测试,它们都是一致的.

我的问题是:它只是一个实现的特点,我不应该依赖它,或者一个可以安全依赖的标准化行为?(Bash docs似乎对这个案子一无所知).

Yoo*_* N. 6

在写这个问题时,我发现了似乎可以回答它的信息.

在"类似问题"一节中有一个关于相反情况的问题(当;需要" "时),它有一个非常好的答案,但我们现在唯一需要的是与POSIX描述链接.

以下字词应被视为保留字:

!     {     }      case
do    done  elif   else
esac  fi    for    if
in    then  until  while
Run Code Online (Sandbox Code Playgroud)

只有在没有引用任何字符且该单词用作以下字符时,才会发生此识别:

  • ...
  • 第一个字的以下比其他的保留字一个case,forin
  • ...

这说明类似的} done fi done }结构在POSIX中是完全合法的,并且必须正确识别所有保留字.