Like "real" programming languages, Bash has functions, though in a somewhat limited implementation. A function is a subroutine, a code block that implements a set of operations, a "black box" that performs a specified task. Wherever there is repetitive code, when a task repeats with only slight variations, then consider using a function.
function function_name {
command...
}
function_name () {
command...
}
This second form will cheer the hearts of C programmers (and is more portable).
As in C, the function's opening bracket may optionally appear on the second line.
function_name ()
{
command...
}
Functions are called, triggered, simply by invoking their names.
Example 23-1. Simple function
#!/bin/bash funky () { echo "This is a funky function." echo "Now exiting funky function." } # Function declaration must precede call. # Now, call the function. funky exit 0 |
The function definition must precede the first call to it. There is no method of "declaring" the function, as, for example, in C.
# f1 # Will give an error message, since function "f1" not yet defined. # However... f1 () { echo "Calling function \"f2\" from within function \"f1\"." f2 } f2 () { echo "Function \"f2\"." } f1 # Function "f2" is not actually called until this point, # although it is referenced before its definition. # This is permissable. # Thanks, S.C. |
It is even possible to nest a function within another function, although this is not very useful.
f1 () { f2 () # nested { echo "Function \"f2\", inside \"f1\"." } } # f2 # Gives an error message. f1 # Does nothing, since calling "f1" does not automatically call "f2". f2 # Now, it's all right to call "f2", # since its definition has been made visible by calling "f1". # Thanks, S.C. |
Function declarations can appear in unlikely places, even where a command would otherwise go.
ls -l | foo() { echo "foo"; } # Permissable, but useless. if [ "$USER" = bozo ] then bozo_greet () # Function definition embedded in an if/then construct. { echo "Hello, Bozo." } fi bozo_greet # Works only for Bozo, and other users get an error. # Something like this might be useful in some contexts. NO_EXIT=1 # Will enable function definition below. [[ $NO_EXIT -eq 1 ]] && exit() { true; } # Function definition in an "and-list". # If $NO_EXIT is 1, declares "exit ()". # This disables the "exit" builtin by aliasing it to "true". exit # Invokes "exit ()" function, not "exit" builtin. # Thanks, S.C. |