unset myVariable i;
while [ -z "$i" ]; do
read myVariable;
echo "myVariable : '$myVariable'";
i=foo;
done;
echo "myVariable : '$myVariable'"
(unset
コマンドの再生を許可します)
任意のキーを押して+Enterキーを押すと、次のようになります。
myVariable : '[what you typed]'
myVariable : '[what you typed]'
値がループmyVariable
の外側に存在します。while
今試してください:
tmpFile=$(mktemp);
echo -e 'foo\nbar\nbaz' >> "$tmpFile"
while read myVariable; do
otherVariable=whatever;
echo "myVariable : '$myVariable', otherVariable : '$otherVariable'";
done < "$tmpFile";
echo "myVariable : '$myVariable', otherVariable : '$otherVariable'";
rm "$tmpFile"
あなたは得るでしょう:
myVariable : 'foo', otherVariable : 'whatever'
myVariable : 'bar', otherVariable : 'whatever'
myVariable : 'baz', otherVariable : 'whatever'
myVariable : '', otherVariable : 'whatever'
myVariable
ループを出ると値が失われます。
なぜ別の行動をするのですか?わからない範囲指定のコツがありますか?
注:GNU bashバージョン4.4.12(1)リリース(x86_64-pc-linux-gnu)の実行
答え1
while read myVariable; do
myVariable
ループを出ると値が失われます。
いいえ、myVariable
前回取得した値がありますread
。スクリプトは、最後の改行文字の次の位置に達するまでファイルから読み取られます。その後、最終read
呼び出しはファイルから何も取得せず、myVariable
それに応じて空の文字列に設定され、区切り文字(改行)が表示されないため、エラー値で終了します。その後、サイクルは終了する。
read
最後の改行の後に不完全な行がある場合は、最後にNULL以外の値を取得できます。
$ printf 'abc\ndef\nxxx' |
{ while read a; do echo "got: $a"; done; echo "end: $a"; }
got: abc
got: def
end: xxx
あるいは、while read a || [ "$a" ]; do ...
ループ本体の最後の行の断片を処理するために使用されます。
答え2
whileループにパイプを接続しているため、whileループを実行するためのサブシェルが作成されます。このサブプロセスには独自の環境コピーがあり、UNIXプロセスと同様に、どの変数も親プロセスに戻すことはできません。
この場合、done < "$tmpFile"
リダイレクトはbashにサブシェル(パイプ用)を作成するように強制します。
から引用bash 変数の範囲スタックオーバーフローに。
答え3
2番目の例では、while
リダイレクトされた入力を含むループを使用します。
これはusingを読み取り、多くの< "$tmpFile"
シェルがこの場合のサブシェルを生成します。を使用してこのスクリプトを実行してみることができますksh93
。ksh93
この場合、サブシェルは作成されません。
場合によっては、理由は完全に異なります。
最初の例では、入力から1行を読み取ります。
2番目の例では、
EOF
到達するまで読みます。
コマンドread
は入力を読み取り、入力を文字に分割し、単語IFS
を変数引数に代入しますread
。
コマンド引数として変数よりも単語が多い場合、read
最後の変数は残りの単語を連結します。
変数よりも単語数が少ない場合、他の変数にはNULL値が割り当てられます。
をクリックしたので、EOF
単語を読み取らずに代わりに1つ以上の変数を引数として渡しましたread
。これにより、すべての変数にNULL値が割り当てられます。
したがって、予期しないことが発生します。EOF
これによりwhile
ループが終了し、echo
ループ内にコマンドは表示されませんが、この場合、ループの後のwhile
最後のコマンドのみが表示されます。echo
while
EOF
この final はecho
hit から消去された変数の内容を出力しますEOF
。