📄 loops.html
字号:
> <AHREF="loops.html#WHILENOBRACKETS">are <SPANCLASS="emphasis"><ICLASS="EMPHASIS">not</I></SPAN> mandatory</A> in a <ICLASS="FIRSTTERM">while</I> loop. See, for example, the <AHREF="internal.html#GETOPTSX">getopts construct</A>.</P><DIVCLASS="EXAMPLE"><HR><ANAME="EX25"></A><P><B>Example 10-14. Simple <ICLASS="FIRSTTERM">while</I> loop</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 var0=0 4 LIMIT=10 5 6 while [ "$var0" -lt "$LIMIT" ] 7 # ^ ^ 8 # Spaces, because these are "test-brackets" . . . 9 do 10 echo -n "$var0 " # -n suppresses newline. 11 # ^ Space, to separate printed out numbers. 12 13 var0=`expr $var0 + 1` # var0=$(($var0+1)) also works. 14 # var0=$((var0 + 1)) also works. 15 # let "var0 += 1" also works. 16 done # Various other methods also work. 17 18 echo 19 20 exit 0</PRE></TD></TR></TABLE><HR></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="EX26"></A><P><B>Example 10-15. Another <ICLASS="FIRSTTERM">while</I> loop</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 echo 4 # Equivalent to: 5 while [ "$var1" != "end" ] # while test "$var1" != "end" 6 do 7 echo "Input variable #1 (end to exit) " 8 read var1 # Not 'read $var1' (why?). 9 echo "variable #1 = $var1" # Need quotes because of "#" . . . 10 # If input is 'end', echoes it here. 11 # Does not test for termination condition until top of loop. 12 echo 13 done 14 15 exit 0</PRE></TD></TR></TABLE><HR></DIV><P><ANAME="WHMULTCOND"></A></P><P>A <ICLASS="FIRSTTERM">while loop</I> may have multiple conditions. Only the final condition determines when the loop terminates. This necessitates a slightly different loop syntax, however.</P><DIVCLASS="EXAMPLE"><HR><ANAME="EX26A"></A><P><B>Example 10-16. <ICLASS="FIRSTTERM">while</I> loop with multiple conditions</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 var1=unset 4 previous=$var1 5 6 while echo "previous-variable = $previous" 7 echo 8 previous=$var1 9 [ "$var1" != end ] # Keeps track of what $var1 was previously. 10 # Four conditions on "while", but only last one controls loop. 11 # The *last* exit status is the one that counts. 12 do 13 echo "Input variable #1 (end to exit) " 14 read var1 15 echo "variable #1 = $var1" 16 done 17 18 # Try to figure out how this all works. 19 # It's a wee bit tricky. 20 21 exit 0</PRE></TD></TR></TABLE><HR></DIV><P><ANAME="WLOOPCSTYLE"></A></P><P>As with a <ICLASS="FIRSTTERM">for loop</I>, a <ICLASS="FIRSTTERM">while loop</I> may employ C-style syntax by using the double parentheses construct (see also <AHREF="dblparens.html#CVARS">Example 9-33</A>).</P><DIVCLASS="EXAMPLE"><HR><ANAME="WHLOOPC"></A><P><B>Example 10-17. C-style syntax in a <ICLASS="FIRSTTERM">while</I> loop</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # wh-loopc.sh: Count to 10 in a "while" loop. 3 4 LIMIT=10 5 a=1 6 7 while [ "$a" -le $LIMIT ] 8 do 9 echo -n "$a " 10 let "a+=1" 11 done # No surprises, so far. 12 13 echo; echo 14 15 # +=================================================================+ 16 17 # Now, repeat with C-like syntax. 18 19 ((a = 1)) # a=1 20 # Double parentheses permit space when setting a variable, as in C. 21 22 while (( a <= LIMIT )) # Double parentheses, and no "$" preceding variables. 23 do 24 echo -n "$a " 25 ((a += 1)) # let "a+=1" 26 # Yes, indeed. 27 # Double parentheses permit incrementing a variable with C-like syntax. 28 done 29 30 echo 31 32 # C programmers can feel right at home in Bash. 33 34 exit 0</PRE></TD></TR></TABLE><HR></DIV><P><ANAME="WHILEFUNC"></A></P><P> Inside its test brackets, a <ICLASS="FIRSTTERM">while loop</I> can call a <AHREF="functions.html#FUNCTIONREF">function</A>. <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 t=0 2 3 condition () 4 { 5 ((t++)) 6 7 if [ $t -lt 5 ] 8 then 9 return 0 # true 10 else 11 return 1 # false 12 fi 13 } 14 15 while condition 16 # ^^^^^^^^^ 17 # Function call -- four loop iterations. 18 do 19 echo "Still going: t = $t" 20 done 21 22 # Still going: t = 1 23 # Still going: t = 2 24 # Still going: t = 3 25 # Still going: t = 4</PRE></TD></TR></TABLE> </P><TABLECLASS="SIDEBAR"BORDER="1"CELLPADDING="5"><TR><TD><DIVCLASS="SIDEBAR"><ANAME="AEN6086"></A><P><ANAME="WHILENOBRACKETS"></A></P><P>Similar to the <AHREF="tests.html#IFGREPREF">if-test</A> construct, a <ICLASS="FIRSTTERM">while</I> loop can omit the test brackets. <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 while condition 2 do 3 ... 4 done</PRE></TD></TR></TABLE></P></DIV></TD></TR></TABLE><P><ANAME="WHILEREADREF2"></A></P><P>By coupling the power of the <AHREF="internal.html#READREF">read</A> command with a <ICLASS="FIRSTTERM">while loop</I>, we get the handy <AHREF="internal.html#WHILEREADREF">while read</A> construct, useful for reading and parsing files. <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 cat $filename | # Supply input from a file. 2 while read line # As long as there is another line to read ... 3 do 4 ... 5 done</PRE></TD></TR></TABLE></P><P><ANAME="WHREDIR"></A></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>A <ICLASS="FIRSTTERM">while loop</I> may have its <TTCLASS="FILENAME">stdin</TT> <AHREF="redircb.html#REDIRREF">redirected to a file</A> by a <SPANCLASS="TOKEN"><</SPAN> at its end.</P><P>A <ICLASS="FIRSTTERM">while loop</I> may have its <TTCLASS="FILENAME">stdin</TT> <AHREF="internal.html#READPIPEREF"> supplied by a pipe</A>.</P></TD></TR></TABLE></DIV></DD><DT><ANAME="UNTILLOOPREF"></A><BCLASS="COMMAND">until</B></DT><DD><P>This construct tests for a condition at the top of a loop, and keeps looping as long as that condition is false (opposite of <ICLASS="FIRSTTERM">while loop</I>).</P><P><P><BCLASS="COMMAND">until</B> [<TTCLASS="REPLACEABLE"><I> condition-is-true </I></TT>]<BR> do <BR> <TTCLASS="REPLACEABLE"><I>燾ommand(s)</I></TT>... <BR> done </P></P><P>Note that an <ICLASS="FIRSTTERM">until loop</I> tests for the terminating condition at the top of the loop, differing from a similar construct in some programming languages.</P><P>As is the case with <ICLASS="FIRSTTERM">for loops</I>, placing the <ICLASS="FIRSTTERM">do</I> on the same line as the condition test requires a semicolon.</P><P><P><BCLASS="COMMAND">until</B> [<TTCLASS="REPLACEABLE"><I> condition-is-true </I></TT>] ; do </P></P><DIVCLASS="EXAMPLE"><HR><ANAME="EX27"></A><P><B>Example 10-18. <ICLASS="FIRSTTERM">until</I> loop</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 END_CONDITION=end 4 5 until [ "$var1" = "$END_CONDITION" ] 6 # Tests condition here, at top of loop. 7 do 8 echo "Input variable #1 " 9 echo "($END_CONDITION to exit)" 10 read var1 11 echo "variable #1 = $var1" 12 echo 13 done 14 15 exit 0</PRE></TD></TR></TABLE><HR></DIV></DD></DL></DIV><P><ANAME="CHOOSELOOP"></A></P><P>How to choose between a <ICLASS="FIRSTTERM">for</I> loop or a <ICLASS="FIRSTTERM">while</I> loop or <ICLASS="FIRSTTERM">until</I> loop? In <BCLASS="COMMAND">C</B>, you would typically use a <ICLASS="FIRSTTERM">for</I> loop when the number of loop iterations is known beforehand. With <ICLASS="FIRSTTERM">Bash</I>, however, the situation is fuzzier. The Bash <ICLASS="FIRSTTERM">for</I> loop is more loosely structured and more flexible than its equivalent in other languages. Therefore, feel free to use whatever type of loop gets the job done in the simplest way.</P></DIV></DIV><H3CLASS="FOOTNOTES">Notes</H3><TABLEBORDER="0"CLASS="FOOTNOTES"WIDTH="100%"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="5%"><ANAME="FTN.AEN5815"HREF="loops.html#AEN5815">[1]</A></TD><TDALIGN="LEFT"VALIGN="TOP"WIDTH="95%"><P><ANAME="ITERATIONREF"></A><ICLASS="FIRSTTERM">Iteration</I>: Repeated execution of a command or group of commands -- usually, but not always -- while a given condition holds, or until a given condition is met.</P></TD></TR></TABLE><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="dblparens.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="nestedloops.html"ACCESSKEY="N">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">The Double Parentheses Construct</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="part3.html"ACCESSKEY="U">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">Nested Loops</TD></TR></TABLE></DIV></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -