Bash – Variable außerhalb einer While-Schleife 2


In der Bash wird jeder loop (while oder for) in einer Subshell gestartet. Die Werte einer Variable sind außerhalb der Subshell nicht verfügbar.


#!/bin/bash
t=0
while read line; do
  t=$(( t + 1 ))
done < /etc/passwd
echo $t

Gibt für $t 0 aus. Wird $t innerhalb von while ausgegeben, stimmt der Wert.

Um die Variable auch nach der Subshell (hier while-loop) zur Verfügung zu haben, muss die Subshell nur erweitert werden.

#!/bin/bash
t=0
cat /etc/passwd | { while read line; do
  t=$(( t + 1 ))
done;
echo $t
}

Hier ist der Wert für $t 0. Der Trick ist { … } – die Subshell läuft komplett im defnierten Bereich.

Zugegeben, dass Beispiel ist nicht besonders glücklich, da man das ganze beim Auslesen einer Datei nur umdrehen muss (oder schlicht wc -l nutzt), um die Variable der Subshell zu behalten. Das Prinzip zeigt sich daran aber sehr gut.

Umgedreht sieht das nämlich so aus:

t=0
while read line; do
  t=$(( t + 1 ))
done < /etc/passwd
echo $t

Auch hier ist $t 0


Hinterlasse einen Kommentar zu Karsten Rehberg Antworten abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

2 Gedanken zu “Bash – Variable außerhalb einer While-Schleife

  • Sergei "Troublemaker" Agarkoff

    Danke aus Russland!
    (English follows)
    I ran into same problem: two nested loops needed to communicate with each other. And I found that inner loop does not return anything into outer one.
    I found a workaround: results were dumped into the temporary file, which was read in outer loop then. But it was slow and inconvenient. Your suggestion worked much better.

  • Karsten Rehberg

    Scheinbar wird heute(2019, Bash 4.2.46) nicht mehr jeder loop in einer Subshell ausgeführt. Der erste Code funktioniert nämlich, t ist nicht 0. Nur bei dem Kontrukt “cat /etc/passwd | while read line” ohne die geschweifte Klammer gibt es das Verhalten noch.