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

时间:2018-02-02 10:21:00

标签: bash shell

this question的答案使我感到困惑。 “他们都错了!”是我的想法,因为我之前在与OP相同或类似的情况下省略了分号,并且一切正常。

关于复合命令的

Documentation似乎证明了这些答案是正确的:

  

{ list; }

     

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

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

  

请注意,只要在命令的语法描述中出现“;”,就可以将其替换为一个或多个换行符。

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

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

{ 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                                       ^    ^  ^    ^

我已经在bash 4.1,4.2,4.4和破折号0.5.7上测试了它们,它们都一致地工作。

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

1 个答案:

答案 0 :(得分:6)

在撰写此问题时,我发现了似乎可以回答的信息。

在“类似问题”部分中有一个question关于相反的情况(当需要“;”时),它有一个非常好的answer,但唯一的事情是我们现在需要的是link to POSIX description

  

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

!     {     }      case
do    done  elif   else
esac  fi    for    if
in    then  until  while
     

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

     
      
  • ...
  •   
  • 除了caseforin
  • 之外的其中一个保留字后面的第一个字   
  • ...
  •   

这表明像} done fi done }这样的结构在POSIX中是完全合法的,并且必须正确识别所有保留字。