6.11. FunctionsBash allows you to define functions that may be invoked as shell commands. Parameters passed to functions are accessible via the standard positional parameter mechanism. Functions must be defined before they are used. There are two ways to define a function, as shown in Figure 6-35.
To invoke a function, supply its name followed by the appropriate parameters. For obvious reasons, the shell does not check the number or type of the parameters. Here's an example of a script that defines and uses a function that takes no parameters: $ cat func1.sh ...list the script. message () # no-parameter function. { echo hi echo there } i=1 while (( i <= 3 )) do message # call the function. let i=i+1 # increment loop count. done $ sh func1.sh ...execute the script. hi there 6.11.1. Using ParametersAs I mentioned previously, parameters are accessible via the standard positional mechanism. Here's an example of a script that passes parameters to a function: $ cat func2.sh ...list the script. f () { echo parameter 1 = $1 # display first parameter. echo parameter list = $* # display entire list. } # main program. f 1 # call with 1 parameter. f cat dog goat # call with 3 parameters. $ sh func2.sh ...execute the script. parameter 1 = 1 parameter list = 1 parameter 1 = cat parameter list = cat dog goat $ _ 6.11.2. Returning from a FunctionThe return command returns the flow of control back to the caller, and has the following syntax shown in Figure 6-36.
When return is used without an argument, the function call returns immediately with the exit code of the last command that was executed in the function; otherwise, it returns with its exit code set to value. If a return command is executed from the main script, it's equivalent to an exit command. The exit code is accessible from the caller via the $? variable. Here's an example function that multiplies its arguments and returns the result: $ cat func3.sh ...list the script. f () # two-parameter function. { (( returnValue = $1 * $2 )) 6.11.3. Access to FunctionsFunctions can be exported to subshells in Bash. This is accomplished with the export built-in, described in Figure 6-37.
Bash also provides a built-in command called local (Figure 6-38) to restrict a variable to be local only to the current function (i.e., its value cannot be passed to a subshell).
Another useful built-in command used when writing functions is the builtin built-in command (Figure 6-39).
6.11.4. RecursionWith careful thought, it's perfectly possible to write recursive functions. Here are two example scripts that implement a recursive version of factorial (). The first uses the exit code to return the result and the second uses standard output to echo the result. Note these scripts are available online; see the Preface for more information. 6.11.4.1. Recursive Factorial, Using Exit Codefactorial () # one-parameter function { if (( $1 <= 1 )) then return 1 # return result in exit code. else typeset tmp # declare two local variables. typeset result (( tmp = $1 - 1 )) factorial $tmp # call recursively. (( result = $? * $1 )) return $result # return result in exit code. fi } # main program. factorial 5 # call function echo factorial 5 = $? # display exit code. 6.11.4.2. Recursive Factorial, Using Standard Outputfactorial() # one-parameter function { if (( $1 <= 1 )) then echo 1 # echo result to standard output. else typeset tmp # declare two local variables. typeset result (( tmp = $1 - 1 )) (( result = 'factorial $tmp' * $1 )) echo $result # echo result to standard output. fi } # echo factorial 5 = 'factorial 5' # display result. 6.11.5. Sharing FunctionsTo share the source code of a function between several scripts, place it in a separate file and then read it using the "." or source built-in commands at the start of the scripts that use the function (Figure 6-40).
In the following example, assume that the source code of one of the previous factorial scripts was saved in a file called "fact.sh": $ cat script.sh ...list the script. . fact.sh # read function source code. echo factorial 5 = 'factorial 5' # call the function. $ sh script.sh ...execute the script. factorial 5 = 120 $ _ |