📄 loops.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><HTML><HEAD><TITLE>Loops and Branches</TITLE><METANAME="GENERATOR"CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+"><LINKREL="HOME"TITLE="Advanced Bash-Scripting Guide"HREF="index.html"><LINKREL="UP"TITLE="Beyond the Basics"HREF="part3.html"><LINKREL="PREVIOUS"TITLE="The Double Parentheses Construct"HREF="dblparens.html"><LINKREL="NEXT"TITLE="Nested Loops"HREF="nestedloops.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="CHAPTER"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="dblparens.html"ACCESSKEY="P">Prev</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom"></TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><AHREF="nestedloops.html"ACCESSKEY="N">Next</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="CHAPTER"><H1><ANAME="LOOPS"></A>Chapter 10. Loops and Branches</H1><TABLEBORDER="0"WIDTH="100%"CELLSPACING="0"CELLPADDING="0"CLASS="EPIGRAPH"><TR><TDWIDTH="45%"> </TD><TDWIDTH="45%"ALIGN="LEFT"VALIGN="TOP"><I><P><I>What needs this iteration, woman?</I></P><P><I>--Shakespeare, <BCLASS="COMMAND">Othello</B></I></P></I></TD></TR></TABLE><P><ANAME="LOOPREF00"></A></P><P>Operations on code blocks are the key to structured and organized shell scripts. Looping and branching constructs provide the tools for accomplishing this.</P><DIVCLASS="SECT1"><H1CLASS="SECT1"><ANAME="LOOPS1"></A>10.1. Loops</H1><P>A <ICLASS="FIRSTTERM">loop</I> is a block of code that <ICLASS="FIRSTTERM">iterates</I> <ANAME="AEN5815"HREF="#FTN.AEN5815">[1]</A> a list of commands as long as the <ICLASS="FIRSTTERM">loop control condition</I> is true.</P><DIVCLASS="VARIABLELIST"><P><B><ANAME="FORLOOPREF1"></A>for loops</B></P><DL><DT><BCLASS="COMMAND">for <TTCLASS="PARAMETER"><I>arg</I></TT> in <TTCLASS="REPLACEABLE"><I>[list]</I></TT></B></DT><DD><P>This is the basic looping construct. It differs significantly from its <ICLASS="FIRSTTERM">C</I> counterpart.</P><P><ANAME="DOINREF"></A></P><P><P><BCLASS="COMMAND">for</B> <TTCLASS="REPLACEABLE"><I>arg</I></TT> in [<TTCLASS="REPLACEABLE"><I>list</I></TT>]<BR> do <BR> <TTCLASS="REPLACEABLE"><I>燾ommand(s)</I></TT>... <BR> done </P></P><DIVCLASS="NOTE"><TABLECLASS="NOTE"WIDTH="90%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="common/note.png"HSPACE="5"ALT="Note"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>During each pass through the loop, <TTCLASS="REPLACEABLE"><I>arg</I></TT> takes on the value of each successive variable in the <TTCLASS="REPLACEABLE"><I>list</I></TT>.</P></TD></TR></TABLE></DIV><P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 for arg in "$var1" "$var2" "$var3" ... "$varN" 2 # In pass 1 of the loop, arg = $var1 3 # In pass 2 of the loop, arg = $var2 4 # In pass 3 of the loop, arg = $var3 5 # ... 6 # In pass N of the loop, arg = $varN 7 8 # Arguments in [list] quoted to prevent possible word splitting.</PRE></TD></TR></TABLE></P><P>The argument <TTCLASS="REPLACEABLE"><I>list</I></TT> may contain <AHREF="special-chars.html#ASTERISKREF">wild cards</A>.</P><P><ANAME="NEEDSEMICOLON"></A></P><P>If <ICLASS="FIRSTTERM">do</I> is on same line as <ICLASS="FIRSTTERM">for</I>, there needs to be a semicolon after list.</P><P><P><BCLASS="COMMAND">for</B> <TTCLASS="REPLACEABLE"><I>arg</I></TT> in [<TTCLASS="REPLACEABLE"><I>list</I></TT>] ; do <BR></P></P><DIVCLASS="EXAMPLE"><HR><ANAME="EX22"></A><P><B>Example 10-1. Simple <ICLASS="FIRSTTERM">for</I> loops</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # Listing the planets. 3 4 for planet in Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune Pluto 5 do 6 echo $planet # Each planet on a separate line. 7 done 8 9 echo 10 11 for planet in "Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune Pluto" 12 # All planets on same line. 13 # Entire 'list' enclosed in quotes creates a single variable. 14 # Why? Whitespace incorporated into the variable. 15 do 16 echo $planet 17 done 18 19 exit 0</PRE></TD></TR></TABLE><HR></DIV><P><ANAME="MULTPARAML"></A></P><P>Each <TTCLASS="USERINPUT"><B>[list]</B></TT> element may contain multiple parameters. This is useful when processing parameters in groups. In such cases, use the <AHREF="internal.html#SETREF">set</A> command (see <AHREF="internal.html#EX34">Example 14-16</A>) to force parsing of each <TTCLASS="USERINPUT"><B>[list]</B></TT> element and assignment of each component to the positional parameters.</P><DIVCLASS="EXAMPLE"><HR><ANAME="EX22A"></A><P><B>Example 10-2. <ICLASS="FIRSTTERM">for</I> loop with two parameters in each [list] element</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # Planets revisited. 3 4 # Associate the name of each planet with its distance from the sun. 5 6 for planet in "Mercury 36" "Venus 67" "Earth 93" "Mars 142" "Jupiter 483" 7 do 8 set -- $planet # Parses variable "planet" 9 #+ and sets positional parameters. 10 # The "--" prevents nasty surprises if $planet is null or 11 #+ begins with a dash. 12 13 # May need to save original positional parameters, 14 #+ since they get overwritten. 15 # One way of doing this is to use an array, 16 # original_params=("$@") 17 18 echo "$1 $2,000,000 miles from the sun" 19 #-------two tabs---concatenate zeroes onto parameter $2 20 done 21 22 # (Thanks, S.C., for additional clarification.) 23 24 exit 0</PRE></TD></TR></TABLE><HR></DIV><P><ANAME="PARAMLI"></A></P><P>A variable may supply the <TTCLASS="USERINPUT"><B>[list]</B></TT> in a <ICLASS="FIRSTTERM">for loop</I>.</P><DIVCLASS="EXAMPLE"><HR><ANAME="FILEINFO"></A><P><B>Example 10-3. <SPANCLASS="emphasis"><ICLASS="EMPHASIS">Fileinfo:</I></SPAN> operating on a file list contained in a variable</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # fileinfo.sh 3 4 FILES="/usr/sbin/accept 5 /usr/sbin/pwck 6 /usr/sbin/chroot 7 /usr/bin/fakefile 8 /sbin/badblocks 9 /sbin/ypbind" # List of files you are curious about. 10 # Threw in a dummy file, /usr/bin/fakefile. 11 12 echo 13 14 for file in $FILES 15 do 16 17 if [ ! -e "$file" ] # Check if file exists. 18 then 19 echo "$file does not exist."; echo 20 continue # On to next. 21 fi 22 23 ls -l $file | awk '{ print $9 " file size: " $5 }' # Print 2 fields. 24 whatis `basename $file` # File info. 25 # Note that the whatis database needs to have been set up for this to work. 26 # To do this, as root run /usr/bin/makewhatis. 27 echo 28 done 29 30 exit 0</PRE></TD></TR></TABLE><HR></DIV><P><ANAME="LIGLOB"></A></P><P>If the <TTCLASS="USERINPUT"><B>[list]</B></TT> in a <ICLASS="FIRSTTERM">for loop</I> contains wild cards (<SPANCLASS="TOKEN">*</SPAN> and <SPANCLASS="TOKEN">?</SPAN>) used in filename expansion, then <AHREF="globbingref.html">globbing</A> takes place.</P><DIVCLASS="EXAMPLE"><HR><ANAME="LISTGLOB"></A><P><B>Example 10-4. Operating on files with a <ICLASS="FIRSTTERM">for</I> loop</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # list-glob.sh: Generating [list] in a for-loop, using "globbing" 3 4 echo 5 6 for file in * 7 # ^ Bash performs filename expansion 8 #+ on expressions that globbing recognizes. 9 do 10 ls -l "$file" # Lists all files in $PWD (current directory). 11 # Recall that the wild card character "*" matches every filename, 12 #+ however, in "globbing," it doesn't match dot-files. 13 14 # If the pattern matches no file, it is expanded to itself. 15 # To prevent this, set the nullglob option 16 #+ (shopt -s nullglob). 17 # Thanks, S.C. 18 done 19 20 echo; echo 21 22 for file in [jx]* 23 do 24 rm -f $file # Removes only files beginning with "j" or "x" in $PWD. 25 echo "Removed file \"$file\"". 26 done 27 28 echo 29 30 exit 0</PRE></TD></TR></TABLE><HR></DIV><P><ANAME="OMITLIST"></A></P><P>Omitting the <TTCLASS="USERINPUT"><B>in [list]</B></TT> part of a <ICLASS="FIRSTTERM">for loop</I> causes the loop to operate on <SPANCLASS="TOKEN">$@</SPAN> -- the <AHREF="variables2.html#POSPARAMREF"> positional parameters</A>. A particularly clever illustration of this is <AHREF="contributed-scripts.html#PRIMES">Example A-16</A>. See also <AHREF="internal.html#REVPOSPARAMS">Example 14-17</A>.</P><DIVCLASS="EXAMPLE"><HR><ANAME="EX23"></A><P><B>Example 10-5. Missing <TTCLASS="USERINPUT"><B>in [list]</B></TT> in a <ICLASS="FIRSTTERM">for</I> loop</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 # Invoke this script both with and without arguments, 4 #+ and see what happens. 5 6 for a 7 do 8 echo -n "$a " 9 done 10 11 # The 'in list' missing, therefore the loop operates on '$@' 12 #+ (command-line argument list, including whitespace). 13 14 echo 15
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -