「while」ループで変数を設定するために「読み取り変数」を使用する場合はグローバル変数ですが、「読み取り中に変数」を使用して変数を設定するときはローカル変数であるのはなぜですか?

「while」ループで変数を設定するために「読み取り変数」を使用する場合はグローバル変数ですが、「読み取り中に変数」を使用して変数を設定するときはローカル変数であるのはなぜですか?
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 ...ループ本体の最後の行の断片を処理するために使用されます。

おすすめ記事