|
|
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 : esacThe 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 . . . ;; esacThe 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.