Global & local variable assignment

var1 is declared local in the function. So during the execution of the function there are two variables named var1: the global one and the local one; but the function can only "see" the local one (the local one "shadows" the global one). So inside the function anything that you do to var1 is done to the local variable; the global var1 is not touched at all.


One way to think of it is to imagine that the local var1="local 1" has the effect of saving the current value of var1, with a promise that at the end of the function it will be restored, and then setting it to "local 1". With this mental model you can then think of all variables as global, and variables being restored at the end of functions.

The example would have been better if instead of calling echo both inside the function and outside it had called another function which had outputted var.

bash$ show(){ printf "   The value of %s in %s is '%s'\n" $1 $2 ${!1} ; }
bash$ bar(){ show v1 bar_$1 ; }
bash$ foo(){ show v1 before_foo ; local v1 ; show v1 after_local ; \ 
               v1="changed"; show v1 after_change ; bar via_foo ; }
bash$ v1="global"
bash$ show v1 global_scope
   The value of v1 in global_scope is 'global'
bash$ foo
   The value of v1 in before_foo is 'global'
   The value of v1 in after_local is ''
   The value of v1 in after_change is 'changed'
   The value of v1 in bar_via_foo is 'changed'
bash$ bar direct
   The value of v1 in bar_direct is 'global'
bash$ show v1 global_scope
   The value of v1 in global_scope is 'global'

Here you can see in the call to bar from inside foo picks up the value of v1 that was established by foo.

A web search for dynamic scope vs lexical scope might help.