corneria
corneria

Reputation: 618

bash variables - understanding scope after while loop

I have a trivial bash script as follows. It takes a csv file as the first parameter.

#!/bin/bash

x="John"
y="Dan"
z="Steve"

echo "x -- $x"
echo "y -- $y"
echo "z -- $z"

INPUT=$1
OLDIFS=$IFS
IFS=,
[ ! -f $INPUT ] && { echo "$INPUT file not found"; exit 1; }
while read x y z
do
        echo "x: $x"
        echo "y: $y"
        echo "z: $z"
done < $INPUT
IFS=$OLDIFS

echo "x -- $x" #no value?
echo "y -- $y" #no value?
echo "z -- $z" #no value?

What I'm wondering is why will variables x, y, and z not hold ANY string values after the while loop runs? I understand that the while loop will change the value of x, y, and z locally. However, I expected x, y, and z to be "John," "Dan," and "Steve," respectively, after the while loop keeping their initially declared values. Or at the very minimum, hold the last values given to it by the csv parsing loop, rather than just empty.

Does the while loop create a subprocess of the original script context and then continue with that child process? Thanks in advance for the explanation.

Edit #1

Adding the csv file for context in case anyone wants to run it:

'P1','2014-10-31',0
'P1','2014-11-01',0
'P2','2014-11-07',0
'P2','2014-11-08',0
'P3','2014-11-14',0
'P3','2014-11-15',0
'P1','2014-11-21',1
'P1','2014-11-22',1
'P2','2014-12-05',1
'P2','2014-12-06',1
'P3','2014-12-12',1
'P3','2014-12-13',1

Upvotes: 1

Views: 439

Answers (2)

chepner
chepner

Reputation: 531125

The while statement (and the read command that it executes) are executed in the same shell. However, read will set the values of x et al. to whatever it reads, including the empty/null line that it sees at the end of the input which causes it to exit with non-zero status.

If you want to preserve the values of the variables when no input is available, you'll have to use different variables in the read, and set x et al. in the body of the loop.

while read a b c; do
    x=$a
    y=$b
    z=$c
done < "$INPUT"

Now, a, b, and c are still global variables as well, but x, y, and z are only modified when read succeeds.

Upvotes: 3

Jonathan
Jonathan

Reputation: 1100

I believe what is going on here is that the read fails, and populates the variables with nothing at the end of the while loop. They still should be in scope.

Clarification: The read fails when it tries to read and there is nothing left to read when it has reached the end of the file. At this point, the while loop exits and the variables are cleared (although the variables are still in scope).

Upvotes: 3

Related Questions