DOC HOME SITE MAP MAN PAGES GNU INFO SEARCH PRINT BOOK
 
Automating frequent tasks

Making multiway choices: the case statement

In explaining the large example program, we have so far ignored lines 82 to 91 These contain a structure designed to choose between several different options: a case statement.

   81 :         case $result in
   82 :               h|H)    help=yes                ;;
   83 :               v)      verbose=yes             ;;
   84 :               l)      record=yes
   85 :                       log=off
   86 :                       LOG=ON                  ;;
   87 :               b)      batch=yes               ;;
   88 :               f)      file=yes
   89 :                       fname=$OPTARG           ;;
   90 :               *)      help=yes                ;;
   91 :         esac
The case command is followed by a variable. This is tested against each of the options in turn, until the esac statement (signifying end of case) is reached.

In addition to setting variables, you can use branches of a case construct to call functions or exit. (An exit statement is used to exit from the current script.)

case statements are not essential to writing scripts that can handle multiway choices, but they make things easier. Consider the following alternative:

if [ ${result} = "h" ]
then
  help=TRUE
else
  if [ ${result} = "H" ]
  then
    help=TRUE
  else
    if [ ${result} = "v" ]
    then
      verbose=TRUE
    else
      if [ ${result} = "l" ]
      then
	record=TRUE
        log=off
        LOG=ON
      else
        if [ ${result} = "b" ]
        then
          batch="yes"
        else
          if [ ${result} = "f" ]
          then
	    file=TRUE
            fname=${OPTARG:-unset}
          else
  	    help=TRUE;;
          fi
        fi
      fi
    fi
  fi
fi

This compound if statement does exactly the same thing as the earlier case statement, but is much harder to read and debug.

The general format of a case construct is as follows:

   case $choice in
   	1)	# carry out action associated with selection 1
   .
   .
   .
   	;;
   	2)	# carry out action associated with selection 2
   .
   .
   .
   	;;
   	3)	# carry out action associated with selection 3
   .
   .
   .
   	;;
   	4)	# carry out action associated with selection 4
   .
   .
   .
   	*)	# carry out action associated with any other selection
   .
   .
   .
   	;;
   esac
The case command evaluates its argument, then selects the matching option from the list and executes the commands between the closing parenthesis following the option and the next double semicolon. In this way, only one out of several possible courses of action can be taken. case tests the argument against its options in order, from top to bottom, and once it has executed the commands associated with an option it skips all the subsequent possibilities and the script continues running on the line after the esac command.

To trap any possible selection use an option like:

   *)	# match any possible argument to case
   .
   .
   .
   ;;
The * option matches any possible argument to the case construct; if no prior option has matched the argument, the commands associated with the * option are automatically carried out. For this reason, the *) option should be placed at the bottom of the case construct; if you place it at the top of the construct, the * option will always be executed before the shell has a chance to check any other options.

There is no effective size limit to a case construct, and unlike an if ... then ... elseif cascade the construct is ``flat''; that is, it is an indivisible structure, and there is consequently no difficulty in working out which construct is being evaluated.


Next topic: Generating a simple menu: the select statement
Previous topic: The && and || operators

© 2003 Caldera International, Inc. All rights reserved.
SCO OpenServer Release 5.0.7 -- 11 February 2003