📄 othertypesv.html
字号:
><ICLASS="FIRSTTERM">Bracket notation</I> for positional parameters leads to a fairly simple way of referencing the <SPANCLASS="emphasis"><ICLASS="EMPHASIS">last</I></SPAN> argument passed to a script on the command line. This also requires <AHREF="bash2.html#VARREFNEW">indirect referencing</A>.</P><P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 args=$# # Number of args passed. 2 lastarg=${!args} 3 # Or: lastarg=${!#} 4 # (Thanks, Chris Monson.) 5 # Note that lastarg=${!$#} doesn't work.</PRE></TD></TR></TABLE></P><P>Some scripts can perform different operations, depending on which name they are invoked with. For this to work, the script needs to check <TTCLASS="VARNAME">$0</TT>, the name it was invoked by. There must also exist symbolic links to all the alternate names of the script. See <AHREF="external.html#HELLOL">Example 15-2</A>.</P><P><ANAME="NULLVAR"></A></P><DIVCLASS="TIP"><TABLECLASS="TIP"WIDTH="90%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="common/tip.png"HSPACE="5"ALT="Tip"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>If a script expects a command line parameter but is invoked without one, this may cause a <ICLASS="FIRSTTERM">null variable assignment</I>, generally an undesirable result. One way to prevent this is to append an extra character to both sides of the assignment statement using the expected positional parameter. </P></TD></TR></TABLE></DIV><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 variable1_=$1_ # Rather than variable1=$1 2 # This will prevent an error, even if positional parameter is absent. 3 4 critical_argument01=$variable1_ 5 6 # The extra character can be stripped off later, like so. 7 variable1=${variable1_/_/} 8 # Side effects only if $variable1_ begins with an underscore. 9 # This uses one of the parameter substitution templates discussed later. 10 # (Leaving out the replacement pattern results in a deletion.) 11 12 # A more straightforward way of dealing with this is 13 #+ to simply test whether expected positional parameters have been passed. 14 if [ -z $1 ] 15 then 16 exit $E_MISSING_POS_PARAM 17 fi 18 19 20 # However, as Fabian Kreutz points out, 21 #+ the above method may have unexpected side-effects. 22 # A better method is parameter substitution: 23 # ${1:-$DefaultVal} 24 # See the "Parameter Substition" section 25 #+ in the "Variables Revisited" chapter.</PRE></TD></TR></TABLE><P>---</P><DIVCLASS="EXAMPLE"><HR><ANAME="EX18"></A><P><B>Example 4-6. <ICLASS="FIRSTTERM">wh</I>, <ICLASS="FIRSTTERM"> whois</I> domain name lookup</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # ex18.sh 3 4 # Does a 'whois domain-name' lookup on any of 3 alternate servers: 5 # ripe.net, cw.net, radb.net 6 7 # Place this script -- renamed 'wh' -- in /usr/local/bin 8 9 # Requires symbolic links: 10 # ln -s /usr/local/bin/wh /usr/local/bin/wh-ripe 11 # ln -s /usr/local/bin/wh /usr/local/bin/wh-cw 12 # ln -s /usr/local/bin/wh /usr/local/bin/wh-radb 13 14 E_NOARGS=65 15 16 17 if [ -z "$1" ] 18 then 19 echo "Usage: `basename $0` [domain-name]" 20 exit $E_NOARGS 21 fi 22 23 # Check script name and call proper server. 24 case `basename $0` in # Or: case ${0##*/} in 25 "wh" ) whois $1@whois.ripe.net;; 26 "wh-ripe") whois $1@whois.ripe.net;; 27 "wh-radb") whois $1@whois.radb.net;; 28 "wh-cw" ) whois $1@whois.cw.net;; 29 * ) echo "Usage: `basename $0` [domain-name]";; 30 esac 31 32 exit $?</PRE></TD></TR></TABLE><HR></DIV><P>---</P><P><ANAME="SHIFTREF"></A></P><P> The <BCLASS="COMMAND">shift</B> command reassigns the positional parameters, in effect shifting them to the left one notch.</P><P><TTCLASS="VARNAME">$1</TT> <--- <TTCLASS="VARNAME">$2</TT>, <TTCLASS="VARNAME">$2</TT> <--- <TTCLASS="VARNAME">$3</TT>, <TTCLASS="VARNAME">$3</TT> <--- <TTCLASS="VARNAME">$4</TT>, etc.</P><P>The old <TTCLASS="VARNAME">$1</TT> disappears, but <SPANCLASS="emphasis"><ICLASS="EMPHASIS"><TTCLASS="VARNAME">$0</TT> (the script name) does not change</I></SPAN>. If you use a large number of positional parameters to a script, <BCLASS="COMMAND">shift</B> lets you access those past <TTCLASS="LITERAL">10</TT>, although <AHREF="othertypesv.html#BRACKETNOTATION">{bracket} notation</A> also permits this.</P><DIVCLASS="EXAMPLE"><HR><ANAME="EX19"></A><P><B>Example 4-7. Using <ICLASS="FIRSTTERM">shift</I></B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # shft.sh: Using 'shift' to step through all the positional parameters 3 4 # Name this script something like shft.sh, 5 #+ and invoke it with some parameters. 6 #+ For example: 7 # sh shft.sh a b c def 23 skidoo 8 9 until [ -z "$1" ] # Until all parameters used up . . . 10 do 11 echo -n "$1 " 12 shift 13 done 14 15 echo # Extra line feed. 16 17 exit 0 18 19 # See also the echo-params.sh script for a "shiftless" 20 #+ alternative method of stepping through the positional params.</PRE></TD></TR></TABLE><HR></DIV><P>The <BCLASS="COMMAND">shift</B> command can take a numerical parameter indicating how many positions to shift.</P><P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # shift-past.sh 3 4 shift 3 # Shift 3 positions. 5 # n=3; shift $n 6 # Has the same effect. 7 8 echo "$1" 9 10 exit 0 11 12 # ======================== # 13 14 15 $ sh shift-past.sh 1 2 3 4 5 16 4 17 18 # However, as Eleni Fragkiadaki, points out, 19 #+ attempting a 'shift' past the number of 20 #+ positional parameters ($#) returns an exit status of 0, 21 #+ and the positional parameters themselves do not change. 22 # This means possibly getting stuck in an endless loop. . . . 23 # For example: 24 # until [ -z "$1" ] 25 # do 26 # echo -n "$1 " 27 # shift 20 # If less than 20 pos params, 28 # done #+ then loop never ends! 29 # 30 # When in doubt, add a sanity check. . . . 31 # shift 20 || break 32 # ^^^^^^^^</PRE></TD></TR></TABLE></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>The <BCLASS="COMMAND">shift</B> command works in a similar fashion on parameters passed to a <AHREF="functions.html#FUNCTIONREF">function</A>. See <AHREF="assortedtips.html#MULTIPLICATION">Example 33-15</A>.</P></TD></TR></TABLE></DIV></DD></DL></DIV></DIV><H3CLASS="FOOTNOTES">Notes</H3><TABLEBORDER="0"CLASS="FOOTNOTES"WIDTH="100%"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="5%"><ANAME="FTN.AEN2193"HREF="othertypesv.html#AEN2193">[1]</A></TD><TDALIGN="LEFT"VALIGN="TOP"WIDTH="95%"><P>The process calling the script sets the <TTCLASS="VARNAME">$0</TT> parameter. By convention, this parameter is the name of the script. See the <AHREF="external.html#MANREF">manpage</A> (manual page) for <BCLASS="COMMAND">execv</B>.</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="untyped.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="quoting.html"ACCESSKEY="N">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">Bash Variables Are Untyped</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="variables.html"ACCESSKEY="U">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">Quoting</TD></TR></TABLE></DIV></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -