As outrageously counter-intuitive as it may first appear, it is still possible to be hit by a scope bug in BASH when commands are executed in a subshell.

I was running through The Advanced Bash-Scripting Guide's "Complex Functions and Function Complexities" (a long but interesting read), and was struggling with some unexpected behaviour - a variable in my the while block of a script wasn't incrementing as expected.

curl "$THIS_URL" | sed -e "s#foo.push(##g" -e "s#}});#}}#g" > $TMP_FILE
while read line; do
done < $TMP_FILE

I found the answer here.

It turns out that this is because pipes cause Bash to perform operations within sub-shells, and variables are specific to whatever sub-shell they're called in. So, once we leave the do/while loop, $COUNTER will again evaluate to 0. Lame!

And refactored my script to use process substitution instead of pipes like this.

while read LINE; do
done < <(curl "$THIS_URL" | | sed -e "s#foo.push(##g" -e "s#}});#}}#g")

Of note is that using this hashbang at the top of the script


failed to execute the process substitution, but replacing it with the binary it was symlinked to (/bin/bash) worked just fine.