Shell – Variables outside of while loop

shellshell-script

I am trying to echo the variables $f1, $f2, etcetera, outside of the while loop shown below. From what I understand, the scope of the variable is not correct. Therefore I tried a few of the workarounds as shown here: http://mywiki.wooledge.org/BashFAQ/024

while IFS=: read -r f1 f2 f3 f4 f5 f6 f7; do
  echo "Username: $f1. Home directory:$f6"
done</etc/passwd

echo $f1

However, I can't seem to reproduce the fix(es) as shown in the link. Can someone provide an applied example on how to fix this issue?

Best Answer

In your link, the variable used outside (linecount) is not defined as a "loop" variable. It's just modified (incremented) inside the body loop, but not in the "while" statement.

This is because when the "read -r f1 f2..." part is called, it reset (prepare) the variables used (f1 ..f7), wait for an input line and assign the variables according to the input. At the end of the file, it does not get any input line (EOF or Pipe Error), returns false, and exits the loop. But it already has reset the variables.

You can figure it for yourself by enabling the "debug mode" by adding set -x before your while statement.

This will produce something like :

++ IFS=:
++ read -r f1 f2 f3 f4 f5 f6 f7
++ echo 'Username: bind. Home directory:/var/cache/bind'
Username: bind. Home directory:/var/cache/bind
++ IFS=:
++ read -r f1 f2 f3 f4 f5 f6 f7
++ echo

You can see the last read being called, then your final "echo $f1".

So, as stated in your link, create another storage variable before your while, assign it the value and then you'll be able to use it :

typeset f0=""
while IFS=: read -r f1 f2 f3 f4 f5 f6 f7; do
  echo "Username: $f1. Home directory:$f6"
  f0="$f1"
done</etc/passwd
echo $f0
Related Question