てきとうなメモ

本の感想とか技術メモとか

bashの'\n'と';'の違い

これもOK。となると、次もOKでしょうよ、当然。

for x in 1 2 3; do; echo $x; done

ガーン、ダメなんだってぇ。

syntax error near unexpected token `;'
シェルスクリプトのセミコロンの打ち所がわからん - 檜山正幸のキマイラ飼育記

for文の改行が';'に置き換えられない場合があるということなんだけども,確かに;の使いどころって分かりにくい.

bash-3.2のparse.yの該当部分を抜き出してみる.

shell_command:  for_command { ... }
        |       case_command { ... }
...
for_command:    ...
        |       FOR WORD newline_list IN word_list list_terminator newline_list 
DO compound_list DONE { ... }
        | ...

newline_listは0個以上の'\n',list_terminatorは';'か'\n'を表している.

compound_listは,複数のリストである.ここでリストと呼んでいるのはword_listのことではなくbashのマニュアルにある以下のものである

A list is a sequence of one or more pipelines separated by one of the
operators ;, &, &&, or ||, and optionally terminated by one of ;, &, or
.

Of these list operators, && and || have equal precedence, followed by ;
and &, which have equal precedence.

で,'\n'はリストの終端に利用できるだけでなく,if文やfor文の中ではリストの分割にも利用できるしリストの先頭に挿入しても問題なく解釈される.なので,以下の各行の'\n'は微妙に意味が違う.

for x in 1 2 3 # word_listの終端
do             # compound_listの先頭
  echo $x      # compound_listの分割
  echo $x      # compound_listの終端
done           # inputunitの終端(ここまでが解釈される1単位になる)

';'の方はリストの分割と終端には利用できるけども,先頭に入力するとsyntax errorになる.

よって,

for x in 1 2 3; do; echo $x; done

は正しくないということらしい.