通常の方法
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
歴史。