Shell functions are a way to group commands for later execution, using a single name for this group, or routine. 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.
Special built-in commands are found before shell functions during command lookup. The special built-ins are: break, :, ., continue, eval, exec, exit, export, readonly, return, set, shift, trap and unset.
Functions either use the syntax
function FUNCTION { COMMANDS; }
or
FUNCTION () { COMMANDS; }
Both define a shell function FUNCTION. The use of the built-in command function is optional; however, if it is not used, parentheses are needed.
The commands listed between curly braces make up the body of the function. These commands are executed whenever FUNCTION is specified as the name of a command. The exit status is the exit status of the last command executed in the body.
Common mistakes | |
---|---|
The curly braces must be separated from the body by spaces, otherwise they are interpreted in the wrong way. The body of a function should end in a semicolon or a newline. |
Functions are like mini-scripts: they can accept parameters, they can use variables only known within the function (using the local shell built-in) and they can return values to the calling shell.
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.
When a function is executed, the arguments to the function become the positional parameters during its execution. The special parameter # that expands to the number of positional parameters is updated to reflect the change. Positional parameter 0 is unchanged. The Bash variable FUNCNAME is set to the name of the function, while it is executing.
If the return 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 # are restored to the values they had prior to the function's execution. If a numeric argument is given to return, that status is returned. A simple example:
[lydia@cointreau ~/test] cat showparams.sh #!/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 [lydia@cointreau ~/test] ./showparams.sh parameter1 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. [lydia@cointreau ~/test] |
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 RETVAL variable in a conditional test, like this one:
if [ $RETVAL -eq 0 ]; then <start the daemon> |
Or like this example from the /etc/init.d/amd script, where Bash's optimazation features are used:
[ $RETVAL = 0 ] && touch /var/lock/subsys/amd |
The commands after && are only executed when the test proves to be true; this is a shorter way to represent an if/then/fi structure.
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 exit $RETVAL.
All functions known by the current shell can be displayed using the set built-in without options. Functions are retained after they are used, unless they are unset after use. The which command also displays functions:
[lydia@cointreau ~] which zless zless is a function zless () { zcat "$@" | "$PAGER" } [lydia@cointreau ~] echo $PAGER less |
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.
Here's one for DOS users:
dir () { ls -F --color=auto -lF --color=always "$@" | less -r } |