Processing Command-Line Options in the Shell
If your shell scripts are to move beyond the ad hoc, you will need to process command-line options beyond the simple:
unixscript $1 $2 $3
And, if other users and software developers are going to use your scripts, a concise approach to processing command-line options will simplify using these options and trapping errors.
his article presents three advanced methods of processing command-line options. The first method is using the UNIX built-in command, getopts, to do the parsing. The other two methods, coding parameters and keyword=value, require writing code to process the command-line options using a while loop and the shift command.
System V supports a built-in command-line parser command, getopts, for both the Bourne and Korn shells. The getopts command placed in a loop will parse single character flags, provided that the flag exists in the argument string succeeding the getopts command and the flag is preceded by a dash.
the general form of getopts is:
getopts optionstring name
where optionstring is one or more valid option letters that getopts recognizes and name is a variable that getopts shifts into with each execution. If an option requires an argument, such as -z argument a colon follows the option letter.
With each execution of getopts, the next command-line option value is placed in variable name for processing. Each execution also bumps the OPTIND counter by one. Using OPTIND allows other command-line options to be processed after the getopts loop terminates.
If the next command-line option requires an argument, that argument is placed in variable OPTARG for processing. If an illegal option occurs, a question mark (?) is placed in variable name.
Listing 1, getopts.sh, demonstrates how to use getopts. The getopts loop: while getopts abz: name requires script execution to be:
getopts.sh -a -b -z zstring anyotheroptions
After the getopts loop terminates, executing the shift command and decreasing OPTIND by 1 allows the processing of any other command-line options not part of getopts option string.
Using getopts is too restrictive for the following reasons:
1. Not every version of Bourne and Korn shells support getopts.
2. Option names can only be one character long.
3. Option names must be preceded by a dash.
Coding the Parameters in the Script
You can eliminate the getopts loop by writing code that parses the command-line options. An example is an any-length option followed by the value (whitespace between option and value is optional). Listing 2, option.sh, demonstrates:
option.sh OPTION astring # white space
option.sh OPTIONastring # no white space
For the whitespace example, the psuedocode would be:
1. Find the option string.
4. Shift to the next option if there is one.
For the no-whitespace example, the psuedocode would be:
1. Find the option string.
2. Set the value cutting the option from the string.
3. Shift to the next option if there is one.
Listing 2, option.sh, demonstrates how to parse the options. Every option processed requires two checks; one check is whitespace between option and value, and the other check is without space. Always make sure that the no-whitespace check for each option is placed first in the loop.
Your shell scripts may be better suited for keyword=value. In that case, we can expand the coding parameters to parse the keyword, the equal sign, and the value. Listing 3, keyword.sh, demonstrates how to process keyword = value or keyword=value.
keword.sh F1=value # no white space
keword.sh F1 = value # white space
the only real difference between parsing options and processing keywords is the added nuisance of checking for and eliminating the equal sign. Once again, always make sure the no-whitespace check for each keyword is placed first in the loop.
With a little effort, the command-line processing in a shell script may approach the flexibility of procedural languages. This article has presented three approaches toward that end.
About the Author
Ed Schaefer is a frequent contributor to Sys Admin. He is a senior programmer analyst for Intel's Factory Information Control System (IFICS) in Hillsboro, OR. His viewpoints on shell scripting or on any other subject in no way reflect Intel's position. He can be reached at email@example.com.