If I set a variable within a while-read loop, sometimes it's local to the loop, sometimes it's global, depending on how the loop is set up. I'm testing this on a Debian Lenny system using both bash and dash with the same results.
For example:
# Pipe command into while-read loop
count=
ls -1 | while read line; do
count=$((count + 1))
done
echo "Count = $count"
In this case, $count is null outside the loop.
The loop set up a separate variable named count and ignored the global variable named count.
Note: Yes, there are better ways to count files in a directory.
So let's try this:
# Redirect file into read-while loop
ls -1 > /tmp/junk
while read line; do
count=$((count + 1))
done < /tmp/junk
rm /tmp/junk
echo "Count = $count"
That works as expected.
We didn't even need to declare count as a global.
Let's try to avoid the temp file by using a Here Doc.
# Redirect Here Document into read-while loop
while read line; do
count=$((count + 1))
done << EOF
$(ls -1)
EOF
echo "Count = $count"
This also works as expected.
The example using the pipe did not work.
My guess is that the pipe somehow launches a child process or subshell or something like that, and variables created within a child are not visible to the parent.
Ok, I can live with that. I think it even says so in the man pages.
But, another thing I noticed is the variable "line" used in all three examples is never visible outside the loop. This would imply a child process as well. Or maybe not?
This is where I am confused.
Why is "line" always invisible outside the loop, but "count" is visible, provided we don't use a pipe?
-MD