web-dev-qa-db-ja.com

さまざまなループで同じ配列に追加し、最後の値のみがBash 4のままになる

私はこのようなものを持っています:

FILES=()
for i in *.map
do
    FILES+=($i)
done

find /var/candy -name "chocolate_[0-9]" | while read snack
do
    FILES+=($snack)
done

for file in ../out/amsterdam/apples/{system.map,vmlinux}
do
    FILES+=($file)
done

ただし、配列には../out/amsterdam/apples/system.mapおよび../out/amsterdam/apples/vmlinuxのみが含まれます。他の値はどうなりましたか?変数が何かを含んでいることを確認するためにエコーしたので、それらはそれらのループに存在することを知っています。

7
Gregg Leventhal

Bash FAQ から取得:

パイプラインにあるループに変数を設定しました。ループが終了した後、なぜ消えるのですか?

上記のように、この潜在的に驚くべき動作の理由は、各SubShellが新しい変数のコンテキストと環境を導入することです。上記のwhileループは、親シェルから取得した「0」の初期値で作成された変数linecountの独自のコピーを使用して、新しいサブシェルで実行されます。その後、このコピーはカウントに使用されます。 whileループが終了すると、サブシェルのコピーは破棄され、親(値が変更されていない)の元の変数行数がechoコマンドで使用されます。

2番目のループでサブシェルが作成されないようにするには、パイプ以外の方法でサブシェルにデータをフィードします。

while read snack; do
    FILES+=($snack)
done < <(find /var/candy -name "chocolate_[0-9]")

while read snack; do
    FILES+=($snack)
done <<<"$(find /var/candy -name "chocolate_[0-9]")"
13
Teresa e Junior