How to raise and take care of shell scripts: Variables
Scope of variables
A variable defined with VAR=wert is valid within this (and only this) shell. If you create a subshell, it's no longer known. To make it known in a subshell, you have to export it:
jan@jack:~/tmp> VAR=1
jan@jack:~/tmp> sh -c "echo $VAR" # $VAR is expanded in the current shell
1
jan@jack:~/tmp> sh -c 'echo $VAR' # $VAR is expanded in the subshell
jan@jack:~/tmp> export VAR # Export
jan@jack:~/tmp> sh -c 'echo $VAR' # now $VAR is known in the subshell
1
jan@jack:~/tmp> VAR=2
jan@jack:~/tmp> sh -c 'echo $VAR' # when modifying the value no new export is necessary
2
What never works: Return modified variable values from a subshell back to the parent. Often this is forgotten when feeding a while loop using a pipe - the pipe creates a subshell (see Sub-Shells):
jan@jack:~/tmp> sh -c 'VAR=3' jan@jack:~/tmp> echo $VAR 2 jan@jack:~/tmp> ls | while read x; do VAR=$x; done jan@jack:~/tmp> echo $VAR 2
There are two ways to return a new value back to the parent process: Output the new value on standard output STDOUT and catch it in the calling process using command substitution or obstain from using subshells (see the next chapters for that):
jan@jack:~/tmp> VAR=`sh -c 'VAR=$((VAR + 1)); echo $VAR'` jan@jack:~/tmp> echo $VAR 3
All shell variables per default are globally defined. There's a trap, especially when you use recursively working functions. A small, almost seamless example:
function recursive {
# a counter
number=0
# depth in recursion; it's a functional argument, I increment
depth=`expr $1 + 1`
# loop, as long as $number is less than 3 and depth is less than 3
while test $number -le 2 -a $depth -le 2
do
# output values
echo "number=$number depth=$depth"
# next recursion depth
recursive $depth
# Trap! $depth has reached 2, because of it's global scope
# and was incremented in every recursive call
number=`expr $number + 1`
# exit loop, because exit condition is reached. Round with $number = 1 never happens
done
}
You can avoid this problem in the bash, when you use the local definition of the variables:
function recursive {
# a counter
local number=0
# depth in recursion; it's a functional argument, I increment
local depth=`expr $1 + 1`
...
}

