Functions

Chapter 23. Functions

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...
}

or

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.

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.