Most shell scripts need to handle command-line arguments - options, filenames, and so on. Articles 
44.15
, 
44.16
, and 
44.17
 show how to parse command lines with any Bourne shell. Those methods have two problems. You can't combine arguments with a single dash, e.g.,  
-abc
 instead of 
-a -b -c
. You also can't specify arguments to options without a space in between, e.g., 
-b
arg
 in addition to 
-b 
arg
. [6]
[6] Although most UNIX commands allow this, it is actually contrary to the Command Syntax Standard Rules in intro of the User's Manual. The version of getopt on the CD-ROM supports this syntax. The getopts we've seen also support this, but may not in future releases.
Your Bourne shell may have a built-in command named getopts . constraints.[7] getopts lets you deal with multiple complex options without these To find out whether your shell has getopts , see your on-line sh or getopts (1) manual page.
[7] Both bash and ksh have it. getopts replaces the old command getopt ; it is better integrated into the shell's syntax and runs more efficiently. C programmers will recognize getopts as very similar to the standard library routine getopt (3).
| getopt | If your shell doesn't have getopts , you can use the command named getopt on the CD-ROM. getopts works differently from getopt ; we won't cover it here. | 
|---|
getopt
 takes two or more arguments.
 The first is a string that can contain letters and colons (
:
). Each letter names a valid option; if a letter is followed by a colon, the option requires an argument. The second and following arguments are the original command-line options; you'll usually give 
"$@"
 (
44.15
)
 to pass all the arguments to 
getopt
.
getopt
 picks each option off the command line, checks to see if the option is valid, and writes the correct option to its standard output. If an option has an argument, 
getopt
 writes the argument after its option. When 
getopt
 finds the first non-option argument (the first argument that doesn't start with a 
-
 character), it outputs two dashes (
-
) and the rest of the arguments. If 
getopt
 finds an invalid option, or an option that should have an argument but doesn't, it prints an error message and returns a non-zero 
status (
44.7
)
.
Your script can use a loop to parse the getopt output. Here's an example script named opttest that shows how getopt works.
| || { : | #!/bin/sh set -- `getopt "ab:" "$@"` || { echo "Usage: `basename $0` [-a] [-b name] [files]" 1>&2 exit 1 } echo "Before loop, command line has: $*" aflag=0 name=NONE while : do case "$1" in -a) aflag=1 ;; -b) shift; name="$1" ;; --) break ;; esac shift done shift # REMOVE THE TRAILING -- echo "aflag=$aflag / name=$name / Files are $*" | 
|---|
The script has two legal options. The 
-a
 option sets the variable named 
aflag
 to 
1
. The 
-b
 option takes a single argument; the argument is stored in the variable named 
name
. Any other arguments are filenames.
The script starts by running 
getopt
 inside 
backquotes (
9.16
)
- and using the 
set
 (
44.19
)
 command to replace the command-line arguments with the 
getopt
 output. The first argument to 
set
, 
-
 (two dashes) (
44.19
)
, is important: it makes sure that 
set
 passes the script's options to 
getopt
 instead of treating them as options to the shell itself. An 
echo
 command shows the output of 
getopt
. Then the loop parses the 
getopt
 output, setting shell variables as it goes. When the loop finds the 
-
 argument from 
getopt
, it quits and leaves the remaining filenames (if any) in the command-line arguments. A second 
echo
 shows what's in the shell variables and on the command line after the loop. Here are a few examples:
%opttestBefore loop, command line has: -- aflag=0 / name=NONE / Files are %opttest -b file1 -a file2 file3Before loop, command line has: -b file1 -a -- file2 file3 aflag=1 / name=file1 / Files are file2 file3 %opttest -q -b file1getopt: illegal option -- q Usage: opttest [-a] [-b name] [files] %opttest -bfile1Before loop, command line has: -b file1 -- aflag=0 / name=file1 / Files are %opttest -abgetopt: option requires an argument -- b Usage: opttest [-a] [-b name] [files]
The advantages of getopt are that it minimizes extra code necessary to process options and fully supports the standard UNIX option syntax (as specified in intro of the User's Manual).
- ,