How to Use 'case' Statement in Shell Script

The case Statement

The if/then/else construct makes it easy to write programs that choose between two alternatives. Sometimes, however, a program needs to choose one of several alternatives. You could do this by using the if/then/elif/else construct, but in many cases it is more convenient to use the case statement. The syntax for the case statement is:

case value in
pattern1)
        statement1
        ...
        statementN
        ;;
pattern2)
        statement1
        ...
        statementN
        ;;
*)
        statement1
        ...
	statementN
	;;
esac

In the syntax given for the case statement, value refers to any value, but it is usually the value of some variable. The patterns used in the case statement can be any pattern, including the shell metacharacters.

Include two semicolon terminators (that is, ;;) after the last statement in the group for each pattern. This prohibits the shell from falling through to the statements for the next pattern and executing them. Think of ;; as saying “Break out of the case statement now and go to the statement that follows the esac statement.”

The last pattern in a case statement is often the * metacharacter. If the value of the variable being tested does not match any of the other patterns, it always matches the * metacharacter. This is often called the default pattern match, and it is analogous to the else statement in the if constructs. The patterns used in the case statement can be any pattern, including the shell metacharacters listed in Table7-3.

Example of Using the case Statement

Let us see an example to use case statement in place of the if statement. We will write a script to find the days in a month including days in february. The first two patterns within the case statement are the string patterns that the variable mth (month of the year) was compared against.

The last pattern in the case statement is the * metacharacter. If mth does not match the first two patterns, it always matches this one. It is analogous to the else within an if statement.

$ cat case.ksh
#!/bin/ksh

# Script name: case.ksh

mth=$(date +%m)

case "$mth" in
02)
        print "February usually has 28 days."
        print "If it is a leap year, it has 29 days."
        ;;

04|06|09|11)
         print "The current month has 30 days."
		 ;;
*)
        print "The current month has 31 days."
        ;;
esac
$ date
Tue Oct 16 08:25:16 PDT 2009
$ ./case.ksh
The current month has 31 days.

Replacing Complex if Statements With a case Statement

When you have many alternatives to check a variable against, the syntax for an if/then/elif/else can get very confusing. Many shell programmers use the case statement in these situations.

The snoopy example below was written with if/then/elif/else statement.

$ cat snoopy2.ksh
#!/bin/ksh

# Script name: snoopy2.ksh

name=snoopy

if [[ "$name" == "snoopy" ]]
then
echo "It was a dark and stormy night."
elif [[ "$name" == "charlie" ]]
then
echo "You’re a good man Charlie Brown."
elif [[ "$name" == "lucy" ]]
then
echo "The doctor is in."
elif [[ "$name" == "schroeder" ]]
then
echo "In concert."
else
echo "Not a Snoopy character."
fi

You can rewrite it with an easier-to-read case statement as follows.

$ cat snoopy3.ksh
#!/bin/ksh

# Script name: snoopy3.ksh

name=snoopy
case $name in
"snoopy")
         echo "It was a dark and stormy night."
		 ;;
"charlie")
        echo "You’re a good man Charlie Brown."
        ;;
"lucy")
        echo "The doctor is in."
		;;
"schroeder")
        echo "In concert."
		;;
*)
        echo "Not a Snoopy character."
		;;
esac

The following example is compressed. It performs the same operations as the previous example; however, it places several statements on the same line and does not have blank lines.

#!/bin/ksh
case $name in
"snoopy") echo "It was a dark and stormy night." ;;
"charlie") echo "You’re a good man Charlie Brown." ;;
"lucy") echo "The doctor is in." ;;
"schroeder") echo "In concert." ;;
*) echo "Not a Snoopy character." ;;
esac

The exit Statement

The exit statement terminates the execution of the entire script. It is most often used if the input requested from the user is incorrect, a statement ran unsuccessfully, or some other error occurred

The exit statement takes an optional argument that is an integer. This number is passed back to the parent shell, where it is stored in the shell reserved $? variable. A nonzero integer argument to the exit statement means that the script ran unsuccessfully. A zero argument means the script ran successfully.

If no argument is given to the exit statement, the shell uses the current value of the $? variable.

$ cat /etc/init.d/volmgt
#!/sbin/sh
#
# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#
# ident "@(#)volmgt     1.9     06/01/20 SMI"
case "$1" in
’start’)
        if [ -f /etc/vold.conf -a -f /usr/sbin/vold -a \
		"${_INIT_ZONENAME:=‘/sbin/zonename‘}" = "global" ]; then
		echo ’volume management starting.’
		svcadm enable svc:/system/filesystem/volfs:default
		fi
        ;;
’stop’)
        svcadm disable svc:/system/filesystem/volfs:default
		;;
*)
        echo "Usage: $0 { start | stop }"
        exit 1
		;;
esac
exit 0
$ /etc/init.d/volmgt go
Usage: /etc/init.d/volmgt { start | stop }
$ echo $?
1
$ /etc/init.d/volmgt start
volume management starting.
$ echo $?
0

The exit statement is often used to terminate a script because of unexpected user input or the occurrence of an error.