⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 functions.html

📁 Shall高级编程
💻 HTML
📖 第 1 页 / 共 3 页
字号:
  27&nbsp;  28&nbsp;echo  29&nbsp;     30&nbsp;echo "Nothing passed."     31&nbsp;func2                          # Called with no params  32&nbsp;echo  33&nbsp;  34&nbsp;  35&nbsp;echo "Zero-length parameter passed."  36&nbsp;func2 ""                       # Called with zero-length param  37&nbsp;echo  38&nbsp;  39&nbsp;echo "Null parameter passed."  40&nbsp;func2 "$uninitialized_param"   # Called with uninitialized param  41&nbsp;echo  42&nbsp;  43&nbsp;echo "One parameter passed."     44&nbsp;func2 first           # Called with one param  45&nbsp;echo  46&nbsp;  47&nbsp;echo "Two parameters passed."     48&nbsp;func2 first second    # Called with two params  49&nbsp;echo  50&nbsp;  51&nbsp;echo "\"\" \"second\" passed."  52&nbsp;func2 "" second       # Called with zero-length first parameter  53&nbsp;echo                  # and ASCII string as a second one.  54&nbsp;  55&nbsp;exit 0</PRE></TD></TR></TABLE><HR></DIV><P><ANAME="FSHIFTREF"></A></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="othertypesv.html#SHIFTREF">shift</A>        command works on arguments passed to functions (see <AHREF="assortedtips.html#MULTIPLICATION">Example 33-15</A>).</P></TD></TR></TABLE></DIV><P>But, what about command-line arguments passed to the script?         Does a function see them? Well, let's clear up the confusion.</P><DIVCLASS="EXAMPLE"><HR><ANAME="FUNCCMDLINEARG"></A><P><B>Example 23-3. Functions and command-line args passed to the script</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;#!/bin/bash   2&nbsp;# func-cmdlinearg.sh   3&nbsp;#  Call this script with a command-line argument,   4&nbsp;#+ something like $0 arg1.   5&nbsp;   6&nbsp;   7&nbsp;func ()   8&nbsp;   9&nbsp;{  10&nbsp;echo "$1"  11&nbsp;}  12&nbsp;  13&nbsp;echo "First call to function: no arg passed."  14&nbsp;echo "See if command-line arg is seen."  15&nbsp;func  16&nbsp;# No! Command-line arg not seen.  17&nbsp;  18&nbsp;echo "============================================================"  19&nbsp;echo  20&nbsp;echo "Second call to function: command-line arg passed explicitly."  21&nbsp;func $1  22&nbsp;# Now it's seen!  23&nbsp;  24&nbsp;exit 0</PRE></TD></TR></TABLE><HR></DIV><P>In contrast to certain other programming languages,	shell scripts normally pass only value parameters to	functions. Variable names (which are actually	<ICLASS="FIRSTTERM">pointers</I>), if	passed as parameters to functions, will be treated as string	literals.  <SPANCLASS="emphasis"><ICLASS="EMPHASIS">Functions interpret their arguments	literally.</I></SPAN></P><P><ANAME="FUNCPOINTERS"></A></P><P><AHREF="ivr.html#IVRREF">Indirect variable	    references</A> (see <AHREF="bash2.html#EX78">Example 34-2</A>) provide a clumsy	    sort of mechanism for passing variable pointers to	    functions.</P><DIVCLASS="EXAMPLE"><HR><ANAME="INDFUNC"></A><P><B>Example 23-4. Passing an indirect reference to a function</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;#!/bin/bash   2&nbsp;# ind-func.sh: Passing an indirect reference to a function.   3&nbsp;   4&nbsp;echo_var ()   5&nbsp;{   6&nbsp;echo "$1"   7&nbsp;}   8&nbsp;   9&nbsp;message=Hello  10&nbsp;Hello=Goodbye  11&nbsp;  12&nbsp;echo_var "$message"        # Hello  13&nbsp;# Now, let's pass an indirect reference to the function.  14&nbsp;echo_var "${!message}"     # Goodbye  15&nbsp;  16&nbsp;echo "-------------"  17&nbsp;  18&nbsp;# What happens if we change the contents of "hello" variable?  19&nbsp;Hello="Hello, again!"  20&nbsp;echo_var "$message"        # Hello  21&nbsp;echo_var "${!message}"     # Hello, again!  22&nbsp;  23&nbsp;exit 0</PRE></TD></TR></TABLE><HR></DIV><P>The next logical question is whether parameters can be	  dereferenced <SPANCLASS="emphasis"><ICLASS="EMPHASIS">after</I></SPAN> being passed to a	  function.</P><DIVCLASS="EXAMPLE"><HR><ANAME="DEREFERENCECL"></A><P><B>Example 23-5. Dereferencing a parameter passed to a function</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;#!/bin/bash   2&nbsp;# dereference.sh   3&nbsp;# Dereferencing parameter passed to a function.   4&nbsp;# Script by Bruce W. Clare.   5&nbsp;   6&nbsp;dereference ()   7&nbsp;{   8&nbsp;     y=\$"$1"   # Name of variable.   9&nbsp;     echo $y    # $Junk  10&nbsp;  11&nbsp;     x=`eval "expr \"$y\" "`  12&nbsp;     echo $1=$x  13&nbsp;     eval "$1=\"Some Different Text \""  # Assign new value.  14&nbsp;}  15&nbsp;  16&nbsp;Junk="Some Text"  17&nbsp;echo $Junk "before"    # Some Text before  18&nbsp;  19&nbsp;dereference Junk  20&nbsp;echo $Junk "after"     # Some Different Text after  21&nbsp;  22&nbsp;exit 0</PRE></TD></TR></TABLE><HR></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="REFPARAMS"></A><P><B>Example 23-6. Again, dereferencing a parameter passed to a function</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;#!/bin/bash   2&nbsp;# ref-params.sh: Dereferencing a parameter passed to a function.   3&nbsp;#                (Complex Example)   4&nbsp;   5&nbsp;ITERATIONS=3  # How many times to get input.   6&nbsp;icount=1   7&nbsp;   8&nbsp;my_read () {   9&nbsp;  #  Called with my_read varname,  10&nbsp;  #+ outputs the previous value between brackets as the default value,  11&nbsp;  #+ then asks for a new value.  12&nbsp;  13&nbsp;  local local_var  14&nbsp;  15&nbsp;  echo -n "Enter a value "  16&nbsp;  eval 'echo -n "[$'$1'] "'  #  Previous value.  17&nbsp;# eval echo -n "[\$$1] "     #  Easier to understand,  18&nbsp;                             #+ but loses trailing space in user prompt.  19&nbsp;  read local_var  20&nbsp;  [ -n "$local_var" ] &#38;&#38; eval $1=\$local_var  21&nbsp;  22&nbsp;  # "And-list": if "local_var" then set "$1" to its value.  23&nbsp;}  24&nbsp;  25&nbsp;echo  26&nbsp;  27&nbsp;while [ "$icount" -le "$ITERATIONS" ]  28&nbsp;do  29&nbsp;  my_read var  30&nbsp;  echo "Entry #$icount = $var"  31&nbsp;  let "icount += 1"  32&nbsp;  echo  33&nbsp;done    34&nbsp;  35&nbsp;  36&nbsp;# Thanks to Stephane Chazelas for providing this instructive example.  37&nbsp;  38&nbsp;exit 0</PRE></TD></TR></TABLE><HR></DIV><DIVCLASS="VARIABLELIST"><P><B><ANAME="EXITRETURN1"></A>Exit and Return</B></P><DL><DT><BCLASS="COMMAND">exit status</B></DT><DD><P>Functions return a value, called an <ICLASS="FIRSTTERM">exit	      status</I>. The exit status may be explicitly	      specified by a <BCLASS="COMMAND">return</B> statement,	      otherwise it is the exit status of the last command	      in the function (<SPANCLASS="RETURNVALUE">0</SPAN> if	      successful, and a non-zero error code if not). This	      <AHREF="exit-status.html#EXITSTATUSREF">exit status</A>	      may be used in the script by referencing it as	      <AHREF="variables2.html#XSTATVARREF">$?</A>.  This mechanism	      effectively permits script functions to have a <SPANCLASS="QUOTE">"return	      value"</SPAN> similar to C functions.</P></DD><DT><BCLASS="COMMAND">return</B></DT><DD><P><ANAME="RETURNREF"></A></P><P>Terminates a function. A <BCLASS="COMMAND">return</B> command	       <ANAME="AEN17024"HREF="#FTN.AEN17024">[1]</A>	      optionally takes an <ICLASS="FIRSTTERM">integer</I>	      argument, which is returned to the calling script as	      the <SPANCLASS="QUOTE">"exit status"</SPAN> of the function, and	      this exit status is assigned to the variable <AHREF="variables2.html#XSTATVARREF">$?</A>.</P><DIVCLASS="EXAMPLE"><HR><ANAME="MAX"></A><P><B>Example 23-7. Maximum of two numbers</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;#!/bin/bash   2&nbsp;# max.sh: Maximum of two integers.   3&nbsp;   4&nbsp;E_PARAM_ERR=250    # If less than 2 params passed to function.   5&nbsp;EQUAL=251          # Return value if both params equal.   6&nbsp;#  Error values out of range of any   7&nbsp;#+ params that might be fed to the function.   8&nbsp;   9&nbsp;max2 ()             # Returns larger of two numbers.  10&nbsp;{                   # Note: numbers compared must be less than 257.  11&nbsp;if [ -z "$2" ]  12&nbsp;then  13&nbsp;  return $E_PARAM_ERR  14&nbsp;fi  15&nbsp;  16&nbsp;if [ "$1" -eq "$2" ]  17&nbsp;then  18&nbsp;  return $EQUAL  19&nbsp;else  20&nbsp;  if [ "$1" -gt "$2" ]  21&nbsp;  then  22&nbsp;    return $1  23&nbsp;  else  24&nbsp;    return $2  25&nbsp;  fi  26&nbsp;fi  27&nbsp;}  28&nbsp;  29&nbsp;max2 33 34  30&nbsp;return_val=$?  31&nbsp;  32&nbsp;if [ "$return_val" -eq $E_PARAM_ERR ]  33&nbsp;then  34&nbsp;  echo "Need to pass two parameters to the function."  35&nbsp;elif [ "$return_val" -eq $EQUAL ]  36&nbsp;  then  37&nbsp;    echo "The two numbers are equal."  38&nbsp;else  39&nbsp;    echo "The larger of the two numbers is $return_val."  40&nbsp;fi    41&nbsp;  42&nbsp;    43&nbsp;exit 0  44&nbsp;  45&nbsp;#  Exercise (easy):  46&nbsp;#  ---------------  47&nbsp;#  Convert this to an interactive script,  48&nbsp;#+ that is, have the script ask for input (two numbers).</PRE></TD></TR></TABLE><HR></DIV><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>For a function to return a string or array, use a	      dedicated variable.	        <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;count_lines_in_etc_passwd()   2&nbsp;{   3&nbsp;  [[ -r /etc/passwd ]] &#38;&#38; REPLY=$(echo $(wc -l &#60; /etc/passwd))   4&nbsp;  #  If /etc/passwd is readable, set REPLY to line count.   5&nbsp;  #  Returns both a parameter value and status information.   6&nbsp;  #  The 'echo' seems unnecessary, but . . .   7&nbsp;  #+ it removes excess whitespace from the output.   8&nbsp;}   9&nbsp;  10&nbsp;if count_lines_in_etc_passwd  11&nbsp;then  12&nbsp;  echo "There are $REPLY lines in /etc/passwd."  13&nbsp;else  14&nbsp;  echo "Cannot count lines in /etc/passwd."  15&nbsp;fi    16&nbsp;  17&nbsp;# Thanks, S.C.</PRE></TD></TR></TABLE>	    </P></TD></TR></TABLE></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="EX61"></A><P><B>Example 23-8. Converting numbers to Roman numerals</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;#!/bin/bash   2&nbsp;   3&nbsp;# Arabic number to Roman numeral conversion   4&nbsp;# Range: 0 - 200   5&nbsp;# It's crude, but it works.   6&nbsp;   7&nbsp;# Extending the range and otherwise improving the script is left as an exercise.   8&nbsp;   9&nbsp;# Usage: roman number-to-convert  10&nbsp;  11&nbsp;LIMIT=200  12&nbsp;E_ARG_ERR=65  13&nbsp;E_OUT_OF_RANGE=66  14&nbsp;  15&nbsp;if [ -z "$1" ]  16&nbsp;then  17&nbsp;  echo "Usage: `basename $0` number-to-convert"  18&nbsp;  exit $E_ARG_ERR  19&nbsp;fi    20&nbsp;  21&nbsp;num=$1  22&nbsp;if [ "$num" -gt $LIMIT ]  23&nbsp;then  24&nbsp;  echo "Out of range!"  25&nbsp;  exit $E_OUT_OF_RANGE  26&nbsp;fi    27&nbsp;  28&nbsp;to_roman ()   # Must declare function before first call to it.  29&nbsp;{  30&nbsp;number=$1  31&nbsp;factor=$2  32&nbsp;rchar=$3  33&nbsp;let "remainder = number - factor"  34&nbsp;while [ "$remainder" -ge 0 ]  35&nbsp;do  36&nbsp;  echo -n $rchar  37&nbsp;  let "number -= factor"  38&nbsp;  let "remainder = number - factor"  39&nbsp;done    40&nbsp;  41&nbsp;return $number  42&nbsp;       # Exercise:  43&nbsp;       # --------  44&nbsp;       # Explain how this function works.  45&nbsp;       # Hint: division by successive subtraction.  46&nbsp;}  47&nbsp;     48&nbsp;  49&nbsp;to_roman $num 100 C  50&nbsp;num=$?  51&nbsp;to_roman $num 90 LXXXX  52&nbsp;num=$?  53&nbsp;to_roman $num 50 L  54&nbsp;num=$?  55&nbsp;to_roman $num 40 XL  56&nbsp;num=$?

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -