> ## Content Index
> Fetch the complete content index at: https://www.binarysludge.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# BASH variable scope
- URL: https://www.binarysludge.com/2012/08/31/bash-variable-scope/
- Published: 2012-08-31T12:13:13.000Z
- Updated: 2012-09-04T12:42:03.000Z
- Author: Andrew Martin
- Tags: error, bash, linux, system adminstration, #Import 2026-10-22 12:56

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"](http://tldp.org/LDP/abs/html/complexfunct.html?ref=binarysludge.com) (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](http://www.nucleardonkey.net/blog/2007/08/variable%5Fscope%5Fin%5Fbash.html?ref=binarysludge.com).

> 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](http://tldp.org/LDP/abs/html/process-sub.html?ref=binarysludge.com).

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

#!/bin/sh

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