Bash's cat, while, let and pipe lead to strange scoping behavior
-
26-09-2019 - |
Question
So here's my script :
count=0
cat myfile | while read line
do
#some stuff...
let count++
echo $count
done
echo $count
The last echo statement output 0 instead of the number of lines in the file, although the echo statement in the while loop prints the incrementing value.
The problem is with the piping, because, with a simple while loop, the last echo statement prints the correct value. How can I get this to work?
Solution
In Bash, you can use process substitution and avoid the temporary file and the variables in the while
loop will be retained.
count=0
while read -r line # you should almost always use -r
do
#some stuff...
(( count++ )) # alternative form
echo $count
done < <(tac myfile)
echo $count
OTHER TIPS
When using pipes, a new subshell is created and any variables in it are lost after it. Use the following code instead:
count=0
while read line
do
#some stuff...
let count++
echo $count
done < myfile
echo $count
Example with a command: tac
:
count=0
# Create a random file
tmpfile=$(mktemp)
tac myfile > $tmpfile
while read line
do
#some stuff...
let count++
echo $count
done < $tmpfile
# remove temp file
rm $tmpfile
echo $count
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow