old-www/LDP/Bash-Beginners-Guide/html/sect_11_01.html

541 lines
9.6 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML
><HEAD
><TITLE
>Introduction</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK
REL="HOME"
TITLE="Bash Guide for Beginners"
HREF="index.html"><LINK
REL="UP"
TITLE="Functions"
HREF="chap_11.html"><LINK
REL="PREVIOUS"
TITLE="Functions"
HREF="chap_11.html"><LINK
REL="NEXT"
TITLE="Examples of functions in scripts"
HREF="sect_11_02.html"></HEAD
><BODY
CLASS="sect1"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Bash Guide for Beginners</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="chap_11.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Chapter 11. Functions</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="sect_11_02.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="sect1"
><H1
CLASS="sect1"
><A
NAME="sect_11_01"
></A
>11.1. Introduction</H1
><DIV
CLASS="sect2"
><H2
CLASS="sect2"
><A
NAME="sect_11_01_01"
></A
>11.1.1. What are functions?</H2
><P
>Shell functions are a way to group commands for later execution, using a single name for this group, or <EM
>routine</EM
>. The name of the routine must be unique within the shell or script. All the commands that make up a function are executed like regular commands. When calling on a function as a simple command name, the list of commands associated with that function name is executed. A function is executed within the shell in which it has been declared: no new process is created to interpret the commands.</P
><P
>Special built-in commands are found before shell functions during command lookup. The special built-ins are: <B
CLASS="command"
>break</B
>, <B
CLASS="command"
>:</B
>, <B
CLASS="command"
>.</B
>, <B
CLASS="command"
>continue</B
>, <B
CLASS="command"
>eval</B
>, <B
CLASS="command"
>exec</B
>, <B
CLASS="command"
>exit</B
>, <B
CLASS="command"
>export</B
>, <B
CLASS="command"
>readonly</B
>, <B
CLASS="command"
>return</B
>, <B
CLASS="command"
>set</B
>, <B
CLASS="command"
>shift</B
>, <B
CLASS="command"
>trap</B
> and <B
CLASS="command"
>unset</B
>.</P
></DIV
><DIV
CLASS="sect2"
><H2
CLASS="sect2"
><A
NAME="sect_11_01_02"
></A
>11.1.2. Function syntax</H2
><P
>Functions either use the syntax</P
><P
><B
CLASS="command"
>function FUNCTION { COMMANDS; }</B
> </P
><P
>or</P
><P
><B
CLASS="command"
>FUNCTION () { COMMANDS; }</B
> </P
><P
>Both define a shell function <B
CLASS="command"
>FUNCTION</B
>. The use of the built-in command <B
CLASS="command"
>function</B
> is optional; however, if it is not used, parentheses are needed.</P
><P
>The commands listed between curly braces make up the body of the function. These commands are executed whenever <B
CLASS="command"
>FUNCTION</B
> is specified as the name of a command. The exit status is the exit status of the last command executed in the body.</P
><DIV
CLASS="note"
><P
></P
><TABLE
CLASS="note"
WIDTH="100%"
BORDER="0"
><TR
><TD
WIDTH="25"
ALIGN="CENTER"
VALIGN="TOP"
><IMG
SRC="../images/note.gif"
HSPACE="5"
ALT="Note"></TD
><TH
ALIGN="LEFT"
VALIGN="CENTER"
><B
>Common mistakes</B
></TH
></TR
><TR
><TD
>&nbsp;</TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
><P
>The curly braces must be separated from the body by spaces, otherwise they are interpreted in the wrong way.</P
><P
>The body of a function should end in a semicolon or a newline.</P
></TD
></TR
></TABLE
></DIV
></DIV
><DIV
CLASS="sect2"
><H2
CLASS="sect2"
><A
NAME="sect_11_01_03"
></A
>11.1.3. Positional parameters in functions</H2
><P
>Functions are like mini-scripts: they can accept parameters, they can use variables only known within the function (using the <B
CLASS="command"
>local</B
> shell built-in) and they can return values to the calling shell.</P
><P
>A function also has a system for interpreting positional parameters. However, the positional parameters passed to a function are not the same as the ones passed to a command or script.</P
><P
>When a function is executed, the arguments to the function become the positional parameters during its execution. The special parameter <TT
CLASS="varname"
>#</TT
> that expands to the number of positional parameters is updated to reflect the change. Positional parameter <TT
CLASS="varname"
>0</TT
> is unchanged. The Bash variable <TT
CLASS="varname"
>FUNCNAME</TT
> is set to the name of the function, while it is executing.</P
><P
>If the <B
CLASS="command"
>return</B
> built-in is executed in a function, the function completes and execution resumes with the next command after the function call. When a function completes, the values of the positional parameters and the special parameter <TT
CLASS="varname"
>#</TT
> are restored to the values they had prior to the function's execution. If a numeric argument is given to <B
CLASS="command"
>return</B
>, that status is returned. A simple example:</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;<TT
CLASS="prompt"
>[lydia@cointreau ~/test]</TT
> <B
CLASS="command"
>cat <TT
CLASS="filename"
>showparams.sh</TT
></B
>
#!/bin/bash
echo "This script demonstrates function arguments."
echo
echo "Positional parameter 1 for the script is $1."
echo
test ()
{
echo "Positional parameter 1 in the function is $1."
RETURN_VALUE=$?
echo "The exit code of this function is $RETURN_VALUE."
}
test other_param
<TT
CLASS="prompt"
>[lydia@cointreau ~/test]</TT
> <B
CLASS="command"
>./showparams.sh <TT
CLASS="parameter"
><I
>parameter1</I
></TT
></B
>
This script demonstrates function arguments.
Positional parameter 1 for the script is parameter1.
Positional parameter 1 in the function is other_param.
The exit code of this function is 0.
<TT
CLASS="prompt"
>[lydia@cointreau ~/test]</TT
>
</PRE
></FONT
></TD
></TR
></TABLE
><P
>Note that the return value or exit code of the function is often storen in a variable, so that it can be probed at a later point. The init scripts on your system often use the technique of probing the <TT
CLASS="varname"
>RETVAL</TT
> variable in a conditional test, like this one:</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;<B
CLASS="command"
>if <TT
CLASS="parameter"
><I
>[ $RETVAL -eq 0 ]</I
></TT
>; then
&#60;start the daemon&#62;</B
>
</PRE
></FONT
></TD
></TR
></TABLE
><P
>Or like this example from the <TT
CLASS="filename"
>/etc/init.d/amd</TT
> script, where Bash's optimization features are used:</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;<B
CLASS="command"
><TT
CLASS="parameter"
><I
>[ $RETVAL = 0 ]</I
></TT
> &#38;&#38; touch <TT
CLASS="filename"
>/var/lock/subsys/amd</TT
></B
>
</PRE
></FONT
></TD
></TR
></TABLE
><P
>The commands after <B
CLASS="command"
>&#38;&#38;</B
> are only executed when the test proves to be true; this is a shorter way to represent an <B
CLASS="command"
>if/then/fi</B
> structure.</P
><P
>The return code of the function is often used as exit code of the entire script. You'll see a lot of initscripts ending in something like <B
CLASS="command"
>exit <TT
CLASS="varname"
>$RETVAL</TT
></B
>.</P
></DIV
><DIV
CLASS="sect2"
><H2
CLASS="sect2"
><A
NAME="sect_11_01_04"
></A
>11.1.4. Displaying functions</H2
><P
>All functions known by the current shell can be displayed using the <B
CLASS="command"
>set</B
> built-in without options. Functions are retained after they are used, unless they are <B
CLASS="command"
>unset</B
> after use. The <B
CLASS="command"
>which</B
> command also displays functions:</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;<TT
CLASS="prompt"
>[lydia@cointreau ~]</TT
> <B
CLASS="command"
>which <TT
CLASS="filename"
>zless</TT
></B
>
zless is a function
zless ()
{
zcat "$@" | "$PAGER"
}
<TT
CLASS="prompt"
>[lydia@cointreau ~]</TT
> <B
CLASS="command"
>echo <TT
CLASS="varname"
>$PAGER</TT
></B
>
less
</PRE
></FONT
></TD
></TR
></TABLE
><P
>This is the sort of function that is typically configured in the user's shell resource configuration files. Functions are more flexible than aliases and provide a simple and easy way of adapting the user environment.</P
><P
>Here's one for DOS users:</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;dir ()
{
ls -F --color=auto -lF --color=always "$@" | less -r
}
</PRE
></FONT
></TD
></TR
></TABLE
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="chap_11.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="index.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="sect_11_02.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Functions</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="chap_11.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Examples of functions in scripts</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>