Reputation: 7025
My bash version is GNU bash, version 4.3.42(1)-release (x86_64-pc-linux-gnu). This is a simplified version of my script:
#!/bin/bash
touch a.ecl
touch b.ecl
function_syntaxCheckFileName()
{
return 1 # 1 syntax error
}
tmpTotalErrors=0
result=0
echo "DEBUG Starting loop"
find . -name '*.ecl' -print0 | while read -d $'\0' file
do
echo " DEBUG - FILE=$file"
echo " DEBUG0 tmpTotalErrors=$tmpTotalErrors --- result=$result"
function_syntaxCheckFileName "$file"
result=$?
echo " DEBUG1 tmpTotalErrors=$tmpTotalErrors --- result=$result"
tmpTotalErrors=$((tmpTotalErrors + result))
echo " DEBUG2 tmpTotalErrors=$tmpTotalErrors --- result=$result"
done
echo "DEBUG3 tmpTotalErrors=$tmpTotalErrors"
It is designed to be run in path with spaces so I use this iteration
find . -name '*.ecl' -print0 | while read -d $'\0' file
The output is this:
DEBUG Starting loop
DEBUG - FILE=./a.ecl
DEBUG0 tmpTotalErrors=0 --- result=0
DEBUG1 tmpTotalErrors=0 --- result=1
DEBUG2 tmpTotalErrors=1 --- result=1
DEBUG - FILE=./b.ecl
DEBUG0 tmpTotalErrors=1 --- result=1
DEBUG1 tmpTotalErrors=1 --- result=1
DEBUG2 tmpTotalErrors=2 --- result=1
DEBUG3 tmpTotalErrors=0
My problem is that tmpTotalErrors lose its value. It was supposed to be 2 and it is 0.
So my questions are:
Upvotes: 0
Views: 324
Reputation: 121397
Rewrite the loop to avoid subshel by using set +m; shopt -s lastpipe
#!/bin/bash
set +m
shopt -s lastpipe
touch a.ecl
touch b.ecl
function_syntaxCheckFileName()
{
return 1 # 1 syntax error
}
tmpTotalErrors=0
result=0
echo "DEBUG Starting loop"
find . -name '*.ecl' -print0 | while read -d $'\0' file
do
echo " DEBUG - FILE=$file"
echo " DEBUG0 tmpTotalErrors=$tmpTotalErrors --- result=$result"
function_syntaxCheckFileName "$file"
result=$?
echo " DEBUG1 tmpTotalErrors=$tmpTotalErrors --- result=$result"
tmpTotalErrors=$((tmpTotalErrors + result))
echo " DEBUG2 tmpTotalErrors=$tmpTotalErrors --- result=$result"
done
echo "DEBUG3 tmpTotalErrors=$tmpTotalErrors"
It's failing because changes in subshell don't reflect in the parent shell.
Also see this Bash FAQ entry: I set variables in a loop that's in a pipeline. Why do they disappear after the loop terminates? Or, why can't I pipe data to read? which discusses a number of alternative solutions.
Upvotes: 3