通常の方法
bashとかでよくやる方法は
1 2 3 4 5 | |
とする方法。
"$@"はスクリプトの引数を展開し、ダブルクォートしてあると
引数毎に分けてダブルクォートした状態で展開します。
1 2 3 4 | |
"$*"とすると同じく展開しますがダブルクォートが全体について
for文で回すと1つの引数として扱われます。
大概のシェルで同様の動作をします。
これは関数の引数も同じで、
1 2 3 4 5 6 7 8 9 | |
としても
1 2 3 4 | |
となります。
以下も関数でもスクリプトの直接の引数でも同じです。
in無し
実はこれがこんな感じで書けます。
1 2 3 4 5 | |
これでも同じ結果になります。
ここではまず
in "$@"が消えていて、さらにdoの前の;も省略されています。
知らなかったんでbash特有の機能か何かとおも思ったんですが、 これは逆にPOSIX準拠な手法です。
The for Loop (POSIX Shell Command Language)
POSIXのShell Commnad Languageの中のThe for Loopの所に書いてあります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
The Open Group Base Specifications Issue 7, 2018 edition: Shell Command Language
ということで、ここでの定義ではdoが別行になっている形ですが、
下の方にin word...を省略した場合はin "$@"と同じ、とあります。
ということで
1 2 3 4 5 6 | |
のように書くのはPOSIX準拠な書き方で、bash以外でもzshでもfishでもdashでも使えます。
;の省略
doが別行にある場合、inがある場合でも最初の行に;は不要です。
ただし同じ行に書く場合にはinがあれば;は必須です。
これがinがない場合では;を省略できます。
省略でできる、というか、もともとPOSIXでも2016年版までは;なしのもののみだったとのこと。
また、Bourne shellでは;なしのみサポートされています。
shell - What is the purpose of the “do” keyword in Bash for loops? - Unix & Linux Stack Exchange
man bash
bashのマニュアルだと
1 2 3 4 5 6 | |
このような記述になっていて、ここにもin wordがオプションとして扱われなければpositional parameterを使うとあります。
(Positional Parameters以外にspecial Parametersという項目があり、こちらは*などのさらに展開されてPositional Parametersとして扱われるものなどがあります。)
その他の方法
上記以外にも
1 2 3 | |
というよにdo/doneの代わりに{}で囲う書き方もbashやzshで可能です。
zshであればさらに
1 2 3 | |
と、;を抜く事もできます。これはbashではエラーになります。
1 2 3 4 | |
のように行を分ければbashでも;を省略できます。
参考
軽く歴史も含め説明があるQA。
- shell - Bash “for” loop without a “in foo bar…” part - Unix & Linux Stack Exchange
- shell - What is the purpose of the “do” keyword in Bash for loops? - Unix & Linux Stack Exchange
歴史。
