📄 list-cons.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><HTML><HEAD><TITLE>List Constructs</TITLE><METANAME="GENERATOR"CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+"><LINKREL="HOME"TITLE="Advanced Bash-Scripting Guide"HREF="index.html"><LINKREL="UP"TITLE="Advanced Topics"HREF="part5.html"><LINKREL="PREVIOUS"TITLE="Aliases"HREF="aliases.html"><LINKREL="NEXT"TITLE="Arrays"HREF="arrays.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="aliases.html"ACCESSKEY="P">Prev</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom"></TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><AHREF="arrays.html"ACCESSKEY="N">Next</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="CHAPTER"><H1><ANAME="LIST-CONS"></A>Chapter 25. List Constructs</H1><P><ANAME="LISTCONSREF"></A></P><P>The <SPANCLASS="QUOTE">"and list"</SPAN> and <SPANCLASS="QUOTE">"or list"</SPAN> constructs provide a means of processing a number of commands consecutively. These can effectively replace complex nested <BCLASS="COMMAND">if</B>/<BCLASS="COMMAND">then</B> or even <BCLASS="COMMAND">case</B> statements.</P><DIVCLASS="VARIABLELIST"><P><B><ANAME="LCONS1"></A>Chaining together commands</B></P><DL><DT>and list</DT><DD><P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 command-1 && command-2 && command-3 && ... command-n</PRE></TD></TR></TABLE> Each command executes in turn provided that the previous command has given a return value of <SPANCLASS="RETURNVALUE">true</SPAN> (zero). At the first <SPANCLASS="RETURNVALUE">false</SPAN> (non-zero) return, the command chain terminates (the first command returning <SPANCLASS="RETURNVALUE">false</SPAN> is the last one to execute).</P><DIVCLASS="EXAMPLE"><HR><ANAME="EX64"></A><P><B>Example 25-1. Using an <ICLASS="FIRSTTERM">and list</I> to test for command-line arguments</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # "and list" 3 4 if [ ! -z "$1" ] && echo "Argument #1 = $1" && [ ! -z "$2" ] \ 5 && echo "Argument #2 = $2" 6 then 7 echo "At least 2 arguments passed to script." 8 # All the chained commands return true. 9 else 10 echo "Less than 2 arguments passed to script." 11 # At least one of the chained commands returns false. 12 fi 13 # Note that "if [ ! -z $1 ]" works, but its supposed equivalent, 14 # if [ -n $1 ] does not. 15 # However, quoting fixes this. 16 # if [ -n "$1" ] works. 17 # Careful! 18 # It is always best to QUOTE tested variables. 19 20 21 # This accomplishes the same thing, using "pure" if/then statements. 22 if [ ! -z "$1" ] 23 then 24 echo "Argument #1 = $1" 25 fi 26 if [ ! -z "$2" ] 27 then 28 echo "Argument #2 = $2" 29 echo "At least 2 arguments passed to script." 30 else 31 echo "Less than 2 arguments passed to script." 32 fi 33 # It's longer and less elegant than using an "and list". 34 35 36 exit 0</PRE></TD></TR></TABLE><HR></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="ANDLIST2"></A><P><B>Example 25-2. Another command-line arg test using an <ICLASS="FIRSTTERM">and list</I></B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 ARGS=1 # Number of arguments expected. 4 E_BADARGS=65 # Exit value if incorrect number of args passed. 5 6 test $# -ne $ARGS && \ 7 echo "Usage: `basename $0` $ARGS argument(s)" && exit $E_BADARGS 8 # If condition 1 tests true (wrong number of args passed to script), 9 #+ then the rest of the line executes, and script terminates. 10 11 # Line below executes only if the above test fails. 12 echo "Correct number of arguments passed to this script." 13 14 exit 0 15 16 # To check exit value, do a "echo $?" after script termination.</PRE></TD></TR></TABLE><HR></DIV><P><ANAME="ANDDEFAULT"></A></P><P> Of course, an <ICLASS="FIRSTTERM">and list</I> can also <ICLASS="FIRSTTERM">set</I> variables to a default value. <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 arg1=$@ && [ -z "$arg1" ] && arg1=DEFAULT 2 3 # Set $arg1 to command line arguments, if any. 4 # But . . . set to DEFAULT if not specified on command line.</PRE></TD></TR></TABLE> </P></DD><DT><ANAME="ORLISTREF"></A>or list</DT><DD><P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 command-1 || command-2 || command-3 || ... command-n</PRE></TD></TR></TABLE> Each command executes in turn for as long as the previous command returns <SPANCLASS="RETURNVALUE">false</SPAN>. At the first <SPANCLASS="RETURNVALUE">true</SPAN> return, the command chain terminates (the first command returning <SPANCLASS="RETURNVALUE">true</SPAN> is the last one to execute). This is obviously the inverse of the <SPANCLASS="QUOTE">"and list"</SPAN>.</P><DIVCLASS="EXAMPLE"><HR><ANAME="EX65"></A><P><B>Example 25-3. Using <ICLASS="FIRSTTERM">or lists</I> in combination with an <ICLASS="FIRSTTERM">and list</I></B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 # delete.sh, not-so-cunning file deletion utility. 4 # Usage: delete filename 5 6 E_BADARGS=65 7 8 if [ -z "$1" ] 9 then 10 echo "Usage: `basename $0` filename" 11 exit $E_BADARGS # No arg? Bail out. 12 else 13 file=$1 # Set filename. 14 fi 15 16 17 [ ! -f "$file" ] && echo "File \"$file\" not found. \ 18 Cowardly refusing to delete a nonexistent file." 19 # AND LIST, to give error message if file not present. 20 # Note echo message continued on to a second line with an escape. 21 22 [ ! -f "$file" ] || (rm -f $file; echo "File \"$file\" deleted.") 23 # OR LIST, to delete file if present. 24 25 # Note logic inversion above. 26 # AND LIST executes on true, OR LIST on false. 27 28 exit 0</PRE></TD></TR></TABLE><HR></DIV><DIVCLASS="CAUTION"><TABLECLASS="CAUTION"WIDTH="90%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="common/caution.png"HSPACE="5"ALT="Caution"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>If the first command in an <SPANCLASS="QUOTE">"or list"</SPAN> returns <SPANCLASS="RETURNVALUE">true</SPAN>, it <TTCLASS="REPLACEABLE"><I>will</I></TT> execute.</P></TD></TR></TABLE></DIV></DD></DL></DIV><P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 # ==> The following snippets from the /etc/rc.d/init.d/single 2 #+==> script by Miquel van Smoorenburg 3 #+==> illustrate use of "and" and "or" lists. 4 # ==> "Arrowed" comments added by document author. 5 6 [ -x /usr/bin/clear ] && /usr/bin/clear 7 # ==> If /usr/bin/clear exists, then invoke it. 8 # ==> Checking for the existence of a command before calling it 9 #+==> avoids error messages and other awkward consequences. 10 11 # ==> . . . 12 13 # If they want to run something in single user mode, might as well run it... 14 for i in /etc/rc1.d/S[0-9][0-9]* ; do 15 # Check if the script is there. 16 [ -x "$i" ] || continue 17 # ==> If corresponding file in $PWD *not* found, 18 #+==> then "continue" by jumping to the top of the loop. 19 20 # Reject backup files and files generated by rpm. 21 case "$1" in 22 *.rpmsave|*.rpmorig|*.rpmnew|*~|*.orig) 23 continue;; 24 esac 25 [ "$i" = "/etc/rc1.d/S00single" ] && continue 26 # ==> Set script name, but don't execute it yet. 27 $i start 28 done 29 30 # ==> . . .</PRE></TD></TR></TABLE></P><DIVCLASS="IMPORTANT"><TABLECLASS="IMPORTANT"WIDTH="100%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="common/important.png"HSPACE="5"ALT="Important"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>The <AHREF="exit-status.html#EXITSTATUSREF">exit status</A> of an <TTCLASS="USERINPUT"><B>and list</B></TT> or an <TTCLASS="USERINPUT"><B>or list</B></TT> is the exit status of the last command executed.</P></TD></TR></TABLE></DIV><P>Clever combinations of <SPANCLASS="QUOTE">"and"</SPAN> and <SPANCLASS="QUOTE">"or"</SPAN> lists are possible, but the logic may easily become convoluted and require close attention to <AHREF="opprecedence.html#OPPRECEDENCE1">operator precedence rules</A>, and possibly extensive debugging. <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 false && true || echo false # false 2 3 # Same result as 4 ( false && true ) || echo false # false 5 # But *not* 6 false && ( true || echo false ) # (nothing echoed) 7 8 # Note left-to-right grouping and evaluation of statements, 9 #+ since the logic operators "&&" and "||" have equal precedence. 10 11 # It's best to avoid such complexities, unless you know what you're doing. 12 13 # Thanks, S.C.</PRE></TD></TR></TABLE> </P><P>See <AHREF="contributed-scripts.html#DAYSBETWEEN">Example A-7</A> and <AHREF="fto.html#BROKENLINK">Example 7-4</A> for illustrations of using an <TTCLASS="USERINPUT"><B>and / or list</B></TT> to test variables.</P></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="aliases.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="arrays.html"ACCESSKEY="N">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">Aliases</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="part5.html"ACCESSKEY="U">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">Arrays</TD></TR></TABLE></DIV></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -