forループの構文を理解しようとしています。POSIX シェル構文規則:
for_clause : For name do_group
| For name sequential_sep do_group
| For name linebreak in sequential_sep do_group
| For name linebreak in wordlist sequential_sep do_group
最後の項目(ほぼデフォルト)と最初の2つの項目はposixを引用して意味があります。
省略:
in word...
次のようにする必要があります。in "$@"
したがって、最初の2つはシェルスクリプトのパラメータを繰り返すことです。
forループがfor name in; do echo $name; done
。私はまだシェルスクリプトのパラメータを繰り返すと思いましたが、小さなスクリプトを書くことはそうではありません。 forループが少し無視されているようです。では、第三の変形の目的は何ですか?
ベストアンサー1
次のように定義しますwordlist
。
wordlist : wordlist WORD
| WORD
だから1つ以上しかしfor var in ...; do ...; done
、ループは繰り返すことができます。0以上For name linebreak in sequential_sep do_group
だから、状況に対処する必要があります。単語0。
wordlist
~として定義された0個以上の単語:
wordlist : wordlist WORD
| /* empty */
あまり混乱しないかもしれません。
見たらSUSv2、持っている:
for_clause : For name linebreak do_group
| For name linebreak in wordlist sequential_sep do_group
wordlist : wordlist WORD
| WORD
これは、空のリストが許可されないことを意味します。したがって、SUSv3では、以下を追加して欠落を修正したようです。
For name linebreak in sequential_sep do_group
定義を変更する代わりにwordlist
。
ここではシェル言語の構文について話しているので、どこ/拡張すると空のリストが発生する可能性があるのではありませんfor i in $var; do ...; done
。これはすべてシェル言語のPOSIXフォーマットのWORDタグです。for i in $(some cmd); do ...; done
$var
$(some cmd)
$var
$(some cmd)
私たちはい話しますが、for i in; do ...; done
実際にはそうではありません言葉in
と〜の間にあるdo
。
コードが特に役に立たないことに同意します。明示的に何も繰り返さないループを書く理由はありません。考えられるいくつかの理由は次のとおりです。
生成されたコード:
if ...; then
list=' "foo" "bar baz" "$var" '
else
list=
fi
eval '
for i in '"$list"'; do
printf "%s\n" "$i"
done
'
あるいは、sh
スクリプトを生成し、for
明示的なパラメータのループを構成するすべてです。
または、いくつかのコードをコメントアウトします。
for commented_out in; do
this code is commented out
done
このような間:
:||:<<'EOF'
this code is commented out and (harmless) even
if it contains invalid syntax
EOF
もっと寛容になります。
標準を変更することになった変更要求は見つかりませんでしたが、主に既存のすべてのシェル実装が許可するため、変更したようなので標準で禁止するfor i in; do ...; done
必要はありません。
BourneシェルとKornで始まるほとんどの実装(これは注目に値する例外です)のように、これを許可しない妥当な理由がないにもかかわらず、if then ...; else ...; fi
Nor if; then ...; else ...; fi
Nor 1を許可しないことがわかりますif ...; then;else ...; fi
(しかし明らかにそうです)。導入されたので、POSIX仕様ベースのシェルは実際にブロックされます。if $empty; then $empty; else $empty; fi
zsh
sh
1実際に!
パイプの終了状態を無効にするキーワードを持たないBourneシェルでは、Bourneシェルは空のセクションを受け入れないため、セクションに明示的なnullコマンドを使用して代わりにif cmd; then :; else command if cmd fails; fi
作成する必要があります。if ! cmd; then command if cmd fails; fi
:
then
then