Bash – using variables outside a while loop 2


The bash runs every loop (while or for) in a subshell. The values for a variable defined inside such a loop / subshell are not available outside.


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

Returns 0 for $t but inside the loop the value is right.

To use a variable outside a loop, just extend the subshell.

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

The script shows the last value for $t inside the loop. The trick is { … } – the subshell runs in the defined area.

Sure, the example is not very useful. If you would just read a file and get the number of lines, wc -l works also. But you can also execute the shells reverse:

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

$t is always 0.


Leave a comment

Your email address will not be published. Required fields are marked *

2 thoughts on “Bash – using variables outside a while loop

  • 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.