23.2. Local Variables

What makes a variable "local"?

local variables

A variable declared as local is one that is visible only within the block of code in which it appears. It has local "scope". In a function, a local variable has meaning only within that function block.


Example 23-8. Local variable visibility

   1 #!/bin/bash
   2 
   3 func ()
   4 {
   5   local loc_var=23       # Declared local.
   6   echo
   7   echo "\"loc_var\" in function = $loc_var"
   8   global_var=999         # Not declared local.
   9   echo "\"global_var\" in function = $global_var"
  10 }  
  11 
  12 func
  13 
  14 # Now, see if local 'a' exists outside function.
  15 
  16 echo
  17 echo "\"loc_var\" outside function = $loc_var"
  18                                       # "loc_var" outside function = 
  19                                       # Nope, $loc_var not visible globally.
  20 echo "\"global_var\" outside function = $global_var"
  21                                       # "global_var" outside function = 999
  22                                       # $global_var is visible globally.
  23 echo				      
  24 
  25 exit 0

Caution

Before a function is called, all variables declared within the function are invisible outside the body of the function, not just those explicitly declared as local.
   1 #!/bin/bash
   2 
   3 func ()
   4 {
   5 global_var=37    #  Visible only within the function block
   6                  #+ before the function has been called. 
   7 }                # END OF FUNCTION
   8 
   9 echo "global_var = $global_var"  # global_var =
  10                                  #  Function "func" has not yet been called,
  11                                  #+ so $global_var is not visible here.
  12 
  13 func
  14 echo "global_var = $global_var"  # global_var = 37
  15                                  # Has been set by function call.

23.2.1. Local variables make recursion possible.

Local variables permit recursion, [1] but this practice generally involves much computational overhead and is definitely not recommended in a shell script. [2]


Example 23-9. Recursion, using a local variable

   1 #!/bin/bash
   2 
   3 #               factorial
   4 #               ---------
   5 
   6 
   7 # Does bash permit recursion?
   8 # Well, yes, but...
   9 # You gotta have rocks in your head to try it.
  10 
  11 
  12 MAX_ARG=5
  13 E_WRONG_ARGS=65
  14 E_RANGE_ERR=66
  15 
  16 
  17 if [ -z "$1" ]
  18 then
  19   echo "Usage: `basename $0` number"
  20   exit $E_WRONG_ARGS
  21 fi
  22 
  23 if [ "$1" -gt $MAX_ARG ]
  24 then
  25   echo "Out of range (5 is maximum)."
  26   # Let's get real now.
  27   # If you want greater range than this,
  28   # rewrite it in a real programming language.
  29   exit $E_RANGE_ERR
  30 fi  
  31 
  32 fact ()
  33 {
  34   local number=$1
  35   # Variable "number" must be declared as local,
  36   # otherwise this doesn't work.
  37   if [ "$number" -eq 0 ]
  38   then
  39     factorial=1    # Factorial of 0 = 1.
  40   else
  41     let "decrnum = number - 1"
  42     fact $decrnum  # Recursive function call.
  43     let "factorial = $number * $?"
  44   fi
  45 
  46   return $factorial
  47 }
  48 
  49 fact $1
  50 echo "Factorial of $1 is $?."
  51 
  52 exit 0

See also Example A-17 for an example of recursion in a script. Be aware that recursion is resource-intensive and executes slowly, and is therefore generally not appropriate to use in a script.

Notes

[1]

Herbert Mayer defines recursion as "...expressing an algorithm by using a simpler version of that same algorithm..." A recursive function is one that calls itself.

[2]

Too many levels of recursion may crash a script with a segfault.
   1 #!/bin/bash
   2 
   3 recursive_function ()		   
   4 {
   5 (( $1 < $2 )) && f $(( $1 + 1 )) $2;
   6 #  As long as 1st parameter is less than 2nd,
   7 #+ increment 1st and recurse.
   8 }
   9 
  10 recursive_function 1 50000  # Recurse 50,000 levels!
  11 # Segfaults, of course.
  12 
  13 #  Recursion this deep might cause even a C program to segfault,
  14 #+ by using up all the memory allotted to the stack.
  15 
  16 # Thanks, S.C.
  17 
  18 exit 0  # This script will not exit normally.