10.4. Testing and Branching

The case and select constructs are technically not loops, since they do not iterate the execution of a code block. Like loops, however, they direct program flow according to conditions at the top or bottom of the block.

Controlling program flow in a code block

case (in) / esac

The case construct is the shell equivalent of switch in C/C++. It permits branching to one of a number of code blocks, depending on condition tests. It serves as a kind of shorthand for multiple if/then/else statements and is an appropriate tool for creating menus.

case "$variable" in

�"$condition1" )
command...
�;;

�"$condition2" )
command...
�;;

esac

Note

  • Quoting the variables is not mandatory, since word splitting does not take place.

  • Each test line ends with a right paren ).

  • Each condition block ends with a double semicolon ;;.

  • The entire case block terminates with an esac (case spelled backwards).

An exceptionally clever use of case involves testing for command-line parameters.
#! /bin/bash

case "$1" in
"") echo "Usage: ${0##*/} <filename>"; exit 65;;  # No command-line parameters,
                                                  # or first parameter empty.
# Note that ${0##*/} is ${var##pattern} param substitution. Net result is $0.

-*) FILENAME=./$1;;   # If filename passed as argument ($1) starts with a dash,
                      # replace it with ./$1
                      # so further commands don't interpret it as an option.

* ) FILENAME=$1;;     # Otherwise, $1.
esac

A case construct can filter strings for globbing patterns.

select

The select construct, adopted from the Korn Shell, is yet another tool for building menus.

select variable [in list]
do
command...
�break
done

This prompts the user to enter one of the choices presented in the variable list. Note that select uses the PS3 prompt (#? ) by default, but that this may be changed.

If in list is omitted, then select uses the list of command line arguments ($@) passed to the script or to the function in which the select construct is embedded.

Compare this to the behavior of a

for variable [in list]

construct with the in list omitted.

See also Example 35-3.