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.

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]")"

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.