POSIX forループ私が `for name do`(リストに単語なし)構文を許可するのはなぜですか?

POSIX forループ私が `for name do`(リストに単語なし)構文を許可するのはなぜですか?

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 ...; fiNor if; then ...; else ...; fiNor 1を許可しないことがわかりますif ...; then;else ...; fi(しかし明らかにそうです)。導入されたので、POSIX仕様ベースのシェルは実際にブロックされます。if $empty; then $empty; else $empty; fizshsh


1実際に!パイプの終了状態を無効にするキーワードを持たないBourneシェルでは、Bourneシェルは空のセクションを受け入れないため、セクションに明示的なnullコマンドを使用して代わりにif cmd; then :; else command if cmd fails; fi作成する必要があります。if ! cmd; then command if cmd fails; fi:thenthen

おすすめ記事