34.4. Recursion

Can a script recursively call itself? Indeed.


Example 34-6. A (useless) script that recursively calls itself

   1 #!/bin/bash
   2 # recurse.sh
   3 
   4 #  Can a script recursively call itself?
   5 #  Yes, but is this of any practical use?
   6 #  (See the following.)
   7 
   8 RANGE=10
   9 MAXVAL=9
  10 
  11 i=$RANDOM
  12 let "i %= $RANGE"  # Generate a random number between 0 and $MAXVAL.
  13 
  14 if [ "$i" -lt "$MAXVAL" ]
  15 then
  16   echo "i = $i"
  17   ./$0             #  Script recursively spawns a new instance of itself.
  18 fi                 #  Each child script does the same, until
  19                    #+ a generated $i equals $MAXVAL.
  20 
  21 #  Using a "while" loop instead of an "if/then" test causes problems.
  22 #  Explain why.
  23 
  24 exit 0


Example 34-7. A (useful) script that recursively calls itself

   1 #!/bin/bash
   2 # pb.sh: phone book
   3 
   4 # Written by Rick Boivie, and used with permission.
   5 # Modifications by document author.
   6 
   7 MINARGS=1     # Script needs at least one argument.
   8 DATAFILE=./phonebook
   9 PROGNAME=$0
  10 E_NOARGS=70   # No arguments error.
  11 
  12 if [ $# -lt $MINARGS ]; then
  13       echo "Usage: "$PROGNAME" data"
  14       exit $E_NOARGS
  15 fi      
  16 
  17 
  18 if [ $# -eq $MINARGS ]; then
  19       grep $1 "$DATAFILE"
  20 else
  21       ( shift; "$PROGNAME" $* ) | grep $1
  22       # Script recursively calls itself.
  23 fi
  24 
  25 exit 0        #  Script exits here.
  26               #  It's o.k. to put non-hashmarked comments
  27               #+ and data after this point.
  28 
  29 # ------------------------------------------------------------------------
  30 # Sample "phonebook" datafile:
  31 
  32 John Doe        1555 Main St., Baltimore, MD 21228          (410) 222-3333
  33 Mary Moe        9899 Jones Blvd., Warren, NH 03787          (603) 898-3232
  34 Richard Roe     856 E. 7th St., New York, NY 10009          (212) 333-4567
  35 Sam Roe         956 E. 8th St., New York, NY 10009          (212) 444-5678
  36 Zoe Zenobia     4481 N. Baker St., San Franciso, SF 94338   (415) 501-1631
  37 # ------------------------------------------------------------------------
  38 
  39 $bash pb.sh Roe
  40 Richard Roe     856 E. 7th St., New York, NY 10009          (212) 333-4567
  41 Sam Roe         956 E. 8th St., New York, NY 10009          (212) 444-5678
  42 
  43 $bash pb.sh Roe Sam
  44 Sam Roe         956 E. 8th St., New York, NY 10009          (212) 444-5678
  45 
  46 #  When more than one argument passed to script,
  47 #+ prints *only* the line(s) containing all the arguments.

Caution

Too many levels of recursion can exhaust the script's stack space, causing a segfault.