Advanced Bash-Scripting Guide: An in-depth exploration of the art of shell scripting | ||
---|---|---|
Prev | Chapter 34. Miscellany | Next |
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 Francisco, 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. |
Example 34-8. Another (useful) script that recursively calls itself
1 #!/bin/bash 2 # usrmnt.sh, written by Anthony Richardson 3 # Used with permission. 4 5 # usage: usrmnt.sh 6 # description: mount device, invoking user must be listed in the 7 # MNTUSERS group in the /etc/sudoers file. 8 9 # ----------------------------------------------------------------- 10 # This is a usermount script that reruns 11 #+ itself using sudo. A user with the proper 12 #+ permissions only has to type 13 14 # usermount /dev/fd0 /mnt/floppy 15 16 # instead of 17 18 # sudo usermount /dev/fd0 /mnt/floppy 19 20 # I use this same technique for all of my 21 #+ sudo scripts, because I find it convenient. 22 # ----------------------------------------------------------------- 23 24 # If SUDO_COMMAND variable is not set we are not being run through 25 #+ sudo, so rerun ourselves. Pass the user's real and group id . . . 26 27 if [ -z "$SUDO_COMMAND" ] 28 then 29 mntusr=$(id -u) grpusr=$(id -g) sudo $0 $* 30 exit 0 31 fi 32 33 # We will only get here if we are being run by sudo 34 /bin/mount $* -o uid=$mntusr,gid=$grpusr 35 36 exit 0 37 38 # Additional notes (from the author of this script): 39 # ------------------------------------------------- 40 41 # 1) Linux allows the users option in the /etc/fstab 42 # file so that any user can mount removable media. 43 # But, on a server, I like to allow only a few 44 # individuals access to removable media. I find 45 # using sudo gives me more control. 46 47 # 2) I also find sudo to be more convenient than 48 # accomplishing this task through groups. 49 50 # 3) This method gives anyone with proper permissions 51 # root access to the mount command, so be careful 52 # about who you allow access. You can get finer 53 # control over which access can be mounted by using this 54 # same technique in separate mntfloppy, mntcdrom, 55 # and mntsamba scripts. 56 |
Too many levels of recursion can exhaust the script's stack space, causing a segfault. |