📄 recursionsct.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><HTML><HEAD><TITLE>A script calling itself (recursion)</TITLE><METANAME="GENERATOR"CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+"><LINKREL="HOME"TITLE="Advanced Bash-Scripting Guide"HREF="index.html"><LINKREL="UP"TITLE="Miscellany"HREF="miscellany.html"><LINKREL="PREVIOUS"TITLE="Tests and Comparisons: Alternatives"HREF="testsandcomparisons.html"><LINKREL="NEXT"TITLE="Colorizing Scripts"HREF="colorizing.html"><METAHTTP-EQUIV="Content-Style-Type"CONTENT="text/css"><LINKREL="stylesheet"HREF="common/kde-common.css"TYPE="text/css"><METAHTTP-EQUIV="Content-Type"CONTENT="text/html; charset=iso-8859-1"><METAHTTP-EQUIV="Content-Language"CONTENT="en"><LINKREL="stylesheet"HREF="common/kde-localised.css"TYPE="text/css"TITLE="KDE-English"><LINKREL="stylesheet"HREF="common/kde-default.css"TYPE="text/css"TITLE="KDE-Default"></HEAD><BODYCLASS="SECT1"BGCOLOR="#FFFFFF"TEXT="#000000"LINK="#AA0000"VLINK="#AA0055"ALINK="#AA0000"STYLE="font-family: sans-serif;"><DIVCLASS="NAVHEADER"><TABLESUMMARY="Header navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><THCOLSPAN="3"ALIGN="center">Advanced Bash-Scripting Guide: An in-depth exploration of the art of shell scripting</TH></TR><TR><TDWIDTH="10%"ALIGN="left"VALIGN="bottom"><AHREF="testsandcomparisons.html"ACCESSKEY="P">Prev</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom">Chapter 33. Miscellany</TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><AHREF="colorizing.html"ACCESSKEY="N">Next</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="SECT1"><H1CLASS="SECT1"><ANAME="RECURSIONSCT"></A>33.5. A script calling itself (recursion)</H1><P><ANAME="SCRIPTRECURSION"></A></P><P>Can a script <AHREF="localvar.html#RECURSIONREF">recursively</A> call itself? Indeed.</P><DIVCLASS="EXAMPLE"><HR><ANAME="RECURSE"></A><P><B>Example 33-8. A (useless) script that recursively calls itself</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 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 $RANGE - 1. 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 25 26 # Note: 27 # ---- 28 # This script must have execute permission for it to work properly. 29 # This is the case even if it is invoked by an "sh" command. 30 # Explain why.</PRE></TD></TR></TABLE><HR></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="PBOOK"></A><P><B>Example 33-9. A (useful) script that recursively calls itself</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # pb.sh: phone book 3 4 # Written by Rick Boivie, and used with permission. 5 # Modifications by ABS Guide author. 6 7 MINARGS=1 # Script needs at least one argument. 8 DATAFILE=./phonebook 9 # A data file in current working directory 10 #+ named "phonebook" must exist. 11 PROGNAME=$0 12 E_NOARGS=70 # No arguments error. 13 14 if [ $# -lt $MINARGS ]; then 15 echo "Usage: "$PROGNAME" data-to-look-up" 16 exit $E_NOARGS 17 fi 18 19 20 if [ $# -eq $MINARGS ]; then 21 grep $1 "$DATAFILE" 22 # 'grep' prints an error message if $DATAFILE not present. 23 else 24 ( shift; "$PROGNAME" $* ) | grep $1 25 # Script recursively calls itself. 26 fi 27 28 exit 0 # Script exits here. 29 # Therefore, it's o.k. to put 30 #+ non-hashmarked comments and data after this point. 31 32 # ------------------------------------------------------------------------ 33 Sample "phonebook" datafile: 34 35 John Doe 1555 Main St., Baltimore, MD 21228 (410) 222-3333 36 Mary Moe 9899 Jones Blvd., Warren, NH 03787 (603) 898-3232 37 Richard Roe 856 E. 7th St., New York, NY 10009 (212) 333-4567 38 Sam Roe 956 E. 8th St., New York, NY 10009 (212) 444-5678 39 Zoe Zenobia 4481 N. Baker St., San Francisco, SF 94338 (415) 501-1631 40 # ------------------------------------------------------------------------ 41 42 $bash pb.sh Roe 43 Richard Roe 856 E. 7th St., New York, NY 10009 (212) 333-4567 44 Sam Roe 956 E. 8th St., New York, NY 10009 (212) 444-5678 45 46 $bash pb.sh Roe Sam 47 Sam Roe 956 E. 8th St., New York, NY 10009 (212) 444-5678 48 49 # When more than one argument is passed to this script, 50 #+ it prints *only* the line(s) containing all the arguments.</PRE></TD></TR></TABLE><HR></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="USRMNT"></A><P><B>Example 33-10. Another (useful) script that recursively calls itself</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 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 itself using sudo. 11 # A user with the proper permissions only has to type 12 13 # usermount /dev/fd0 /mnt/floppy 14 15 # instead of 16 17 # sudo usermount /dev/fd0 /mnt/floppy 18 19 # I use this same technique for all of my 20 #+ sudo scripts, because I find it convenient. 21 # ---------------------------------------------------------- 22 23 # If SUDO_COMMAND variable is not set we are not being run through 24 #+ sudo, so rerun ourselves. Pass the user's real and group id . . . 25 26 if [ -z "$SUDO_COMMAND" ] 27 then 28 mntusr=$(id -u) grpusr=$(id -g) sudo $0 $* 29 exit 0 30 fi 31 32 # We will only get here if we are being run by sudo. 33 /bin/mount $* -o uid=$mntusr,gid=$grpusr 34 35 exit 0 36 37 # Additional notes (from the author of this script): 38 # ------------------------------------------------- 39 40 # 1) Linux allows the "users" option in the /etc/fstab 41 # file so that any user can mount removable media. 42 # But, on a server, I like to allow only a few 43 # individuals access to removable media. 44 # I find using sudo gives me more control. 45 46 # 2) I also find sudo to be more convenient than 47 # accomplishing this task through groups. 48 49 # 3) This method gives anyone with proper permissions 50 # root access to the mount command, so be careful 51 # about who you allow access. 52 # You can get finer control over which access can be mounted 53 # by using this same technique in separate mntfloppy, mntcdrom, 54 # and mntsamba scripts.</PRE></TD></TR></TABLE><HR></DIV><DIVCLASS="CAUTION"><TABLECLASS="CAUTION"WIDTH="100%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="common/caution.png"HSPACE="5"ALT="Caution"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>Too many levels of recursion can exhaust the script's stack space, causing a segfault.</P></TD></TR></TABLE></DIV></DIV><DIVCLASS="NAVFOOTER"><HRALIGN="LEFT"WIDTH="100%"><TABLESUMMARY="Footer navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top"><AHREF="testsandcomparisons.html"ACCESSKEY="P">Prev</A></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="index.html"ACCESSKEY="H">Home</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><AHREF="colorizing.html"ACCESSKEY="N">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">Tests and Comparisons: Alternatives</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="miscellany.html"ACCESSKEY="U">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><SPANCLASS="QUOTE">"Colorizing"</SPAN> Scripts</TD></TR></TABLE></DIV></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -