Saturday, November 3, 2007

Using "case" Instead of "getopts" To Handle Script Input

Hey There,

I'm sure there are die-hard folks out there (like me), who prefer the getopts function to any other when it comes to parsing command line options for a nice shell script.

However, there are times when it makes more sense to use a "case" statement instead. One the most blatant examples can be seen in almost any init script on your Linux or Unix operating system. The simple rule is: If you're only accepting a very limited amount of input at the command line, there's no sense in over-complicating things. Not to mention the fact that "case" is more likely to port across systems and shells than getopts!

A "case" statement is very simple to write up. Let's take the example of the init script. It will generally accept about 3 arguments: start, stop or restart. Since these scripts are specifically for starting and stopping services, limiting to only those 3 command line options make sense and keeps the scripts brief, which is a benefit at boot-time.

Here's a sample "case" statement for a shell script that accepts the three above-mentioned arguments (only one of three, actually) and will return a usage error if it receives anything it doesn't expect:

case "$1" in
'start' )
/usr/local/bin/yourcommand start
'stop' )
/usr/local/bin/yourcommand stop
'restart' )
/usr/local/bin/yourcommand stop
/usr/local/bin/yourcommand start
* )
echo "Usage: $0 [start|stop|restart]"
exit 1

Pretty simply, the "case" command iterates through the variable option it is told to act upon. Is this situation "$1" which translates, in the shell, to the first argument on the command line. It reads this in, translates it and then compares it to all of the available options it lists. Of course, it will match one of them, since our final option is "*" which is a special character which will match anything.

Note that the Usage output also utilizes a variable: $0. This equates to the name of the called command, exactly as it was called. So if you typed in "./myscript halt" you would get return output of: "Usage: ./myscript [stop|start|restart]" and be returned to the command line.

As you can see, in some cases (no pun intended) "case" makes a better case for utilization than getopts ;)

, Mike