Beim Anhängen an dasselbe Array in verschiedenen Schleifen bleiben nur die letzten Werte Bash 4

7

Ich habe so etwas:

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

Das Array enthält jedoch nur ../out/amsterdam/apples/system.mapund ../out/amsterdam/apples/vmlinux. Was ist mit den anderen Werten passiert? Ich weiß, dass sie in diesen Schleifen vorhanden sind, weil ich wiederholt habe, um sicherzustellen, dass die Variablen etwas enthalten.

Gregg Leventhal
quelle

Antworten:

13

Entnommen aus den Bash FAQ :

Ich setze Variablen in einer Schleife, die sich in einer Pipeline befindet. Warum verschwinden sie nach Beendigung der Schleife?

Der Grund für dieses möglicherweise überraschende Verhalten, wie oben beschrieben, ist, dass jede SubShell einen neuen variablen Kontext und eine neue Umgebung einführt. Die obige while-Schleife wird in einer neuen Subshell mit einer eigenen Kopie der variablen Zeilenanzahl ausgeführt, die mit dem Anfangswert '0' aus der übergeordneten Shell erstellt wurde. Diese Kopie wird dann zum Zählen verwendet. Wenn die while-Schleife beendet ist, wird die Subshell-Kopie verworfen und die ursprüngliche variable Zeilenanzahl des übergeordneten Elements (dessen Wert sich nicht geändert hat) wird im Befehl echo verwendet.

Um zu verhindern, dass in Ihrer zweiten Schleife eine Unterschale erstellt wird, können Sie Daten auf andere Weise als über eine Pipe zu ihr einspeisen:

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]")"
Teresa e Junior
quelle
Was ist, wenn ich eine Funktion wie append () {FILES + = $ 1; } und dann für jede Schleife für i in (was auch immer) tun; füge $ i hinzu; fertig
Gregg Leventhal
Das Beispiel in Ihrem obigen Kommentar funktioniert. Denken Sie daran, dass das aufgetretene Problem nur in der zweiten Schleife vorhanden ist, die die Pipe enthält. Ich werde meine Antwort aktualisieren.
Teresa e Junior