12.12. The Command Line
12.12.1 Processing Command-Line Options with
getopts
If you are writing scripts that require a number of command-line options, positional parameters are not always most efficient. For example, the UNIX/Linux
ls
command takes a number of command-line options and arguments. (An option requires a leading dash; an argument does not.) Options can be passed to the program in several ways:
ls “laFi
,
ls “i “a “l “F
,
ls “ia “F
, and so forth. If you have a script that requires arguments, positional parameters might be used to process the arguments individually, such as
ls “l “i “F
. Each dash option would be stored in
$1
,
$2
, and
$3
, respectively. But, what if the
user
listed all of the options as one dash option, as in
ls “liF
? Now the
“liF
would all be assigned to
$1
in the script. The
getopts
function makes it possible to process command-line options and arguments in the same way they are
processed
by the
ls
program.
[7]
The
getopts
function will allow the
runit
program to process its arguments using a variety of combinations.
[7]
See the UNIX or Linux manual for the C library function
getopt
.
Example 12.68.
(The Command Line)
1 $
runit x n 200 filex
2 $
runit xn200 filex
3 $
runit xy
4 $
runit yx n 30
5 $
runit n250 xy filey
(any other combination of these arguments)
EXPLANATION
-
The program
runit
takes four arguments;
x
is an option,
n
is an option requiring a number argument after it, and
filex
is an argument that stands alone.
-
The program
runit
combines the options
x
and
n
and the number argument
200
;
filex
is also an argument.
-
The program
runit
combines the
x
and
y
options.
-
The program
runit
combines the
y
and
x
options; the
n
option is passed separately as is the number argument,
30
.
-
The program
runit
combines the
n
option with the number argument; the
x
and
y
options are combined and the
filey
is separate.
Before getting into all the details of the
runit
program, we examine the line from the program where
getopts
is used to see how it processes the arguments. The following is a line from the script called
runit
:
while getopts :xyn: name
-
x
,
y
, and
n
are the options.
-
Options typed at the command line begin with either
“
or
+
.
-
Any options that do not contain a
+
or
“
tell
getopts
that the option list is at an end.
-
The
colon
after an option says that the option requires an argument; that is, the
“n
option requires an argument.
-
The colon before an option list says that if you type an illegal option,
getopts
will allow the programmer to handle it. For example, in the command
runit “p
, where
“p
is not one of the legal options,
getopts
will tell you so programmatically. The shell does not print an error message.
-
Each time
getopts
is called, it places the
next
option it finds, without the dash, in the variable
name
. (You can use any variable name here.) If there is a plus sign prepended to the option, then it goes into
name
with the plus sign. If an illegal argument is given,
name
is assigned a question mark; if a required argument is missing,
name
is assigned a colon.
-
OPTIND
is a special variable that is
initialized
to one and is incremented each time
getopts
completes processing a command-line argument to the number of the next argument
getopts
will process.
-
The
OPTARG
variable contains the value of a legal argument, or if an illegal option is given, the value of the illegal option is stored in
OPTARG
.
Sample
getopts
Scripts
The following sample scripts
illustrate
how
getopts
processes arguments.
Example 12.69.
(The Script)
#!/bin/ksh
# Program opts1
# Using getopts First try
1
while getopts xy options
do
2 case $options in
3 x) print "you entered x as an option";;
y) print "you entered y as an option";;
esac
done
-----------------------------------------------------------------
(The Command Line)
4 $
opts1 x
you entered x as an option
5 $
opts1 xy
you entered x as an option
you entered y as an option
6 $
opts1 y
you entered y as an option
7 $
opts1 b
opts1[3]: getopts: b bad option(s)
8 $
opts1 b
EXPLANATION
-
The
getopts
command is used as a condition for the
while
command. The valid options for this program are listed after the
getopts
command; they are
x
and
y
. Each option is
tested
in the body of the loop, one after the other. Each option will be assigned to the variable
options
, without the leading dash. When there are no longer any arguments to process,
getopts
will exit with a nonzero status,
causing
the
while
loop to terminate.
-
The
case
command is used to test each of the possible options found in the
options
variable, either
x
or
y
.
-
If
x
was an option, the string
you entered “x as an option
is displayed.
-
At the command line, the
opts1
script is given an
x
option, a legal option to be processed by
getopts
.
-
At the command line, the
opts1
script is given an
xy
option, legal options to be processed by
getopts
.
-
At the command line, the
opts1
script is given a
y
option, a legal option to be processed by
getopts
.
-
The
opts1
script is given a
b
option, an illegal option.
Getopts
sends an error message.
-
An option without a
“
or
+
prepended to it is not an option and causes
getopts
to stop processing arguments.
Example 12.70.
(The Script)
#!/bin/ksh
# Program opts2
# Using getopts Second try
1
while getopts :xy options
do
2 case $options in
x) print "you entered x as an option";;
y) print "you entered y as an option";;
3
\?) print $OPTARG is not a valid option 1>&2;;
esac
done
------------------------------------------------------------------
(The Command Line)
$
opts2 x
you entered x as an option
$
opts2 y
you entered y as an option
$
opts2 xy
$
opts2 xy
you entered x as an option
you entered y as an option
4 $
opts2 g
g is not a valid option
5 $
opts2 c
c is not a valid option
EXPLANATION
-
The colon
preceding
the option list
prevents
the Korn shell from printing an error message for a bad option. However, if the option is a bad option, a question mark will be assigned to the
options
variable.
-
The
case
command can be used to test for the question mark, allowing you to print your own error message to standard error.
-
If the
options
variable is assigned the question mark, this
case
statement is executed. The question mark is protected with the backslash so that the Korn shell does not see it as a wildcard and try to perform filename substitution.
-
g
is not a legal option. The question mark is assigned to the
options
variable, and
OPTARG
is assigned the illegal option
g
.
-
c
is not a legal option. The question mark is assigned to the
options
variable, and
OPTARG
is assigned the illegal option
c
.
Example 12.71.
(The Script)
#!/bin/ksh
# Program opts3
# Using getopts Third try
1
while getopts :d options
do
case $options in
2 d) print R "d is the ON switch";;
3 +d) print R "+d is the OFF switch";;
\?) print $OPTARG is not a valid option;;
esac
done
# Need the R option with print or the shell tries to use d as a print option
------------------------------------------------------------------
(The Command Line)
4 $
opts3 d
d is the ON switch
5 $
opts3 +d
+d is the OFF switch
6 $
opts3 e
e is not a valid option
7 $
opts3 e
EXPLANATION
-
The
while
command tests the exit status of
getopts
; if
getopts
can successfully process an argument, it returns 0 exit status, and the body of the
while
loop is entered. The colon prepended to the
d
option
tells
getopts
not to print an error message if the user enters an invalid option.
-
One of the legal options is
“d
. If
“d
is entered as an option, the
d
(without the dash) is stored in the
options
variable. (The
“R
option to the
print
command allows the first character in the
print
string to be a dash.)
-
One of the legal options is
+d
. If
+d
is entered as an option, the
d
(with the plus sign) is stored in the options variable.
-
The
“d
option is a legal option to
opts3
.
-
The
+d
option is also a legal option to
opts3
.
-
The
“e
option is invalid. A question mark is stored in
options
if the option is illegal. The illegal argument is stored in
OPTARG
.
-
The option is prepended with
neither
a dash nor a plus sign. The
getopts
command will not process it as an option and returns a nonzero exit status. The
while
loop is
terminated
.
Example 12.72.
(The Script)
#!/bin/ksh
# Program opts4
# Using getopts Fourth try
1 alias USAGE='print "usage: opts4 [-x] filename " >&2'
2
while getopts :x: arguments
do
case $arguments in
3 x) print "$OPTARG is the name of the argument ";;
4 :) print "Please enter an argument after the -x option" >&2
USAGE ;;
5 \?) print "$OPTARG is not a valid option." >&2
USAGE;;
esac
6 print "$OPTIND" #
The number of the next argument to be processed
done
-----------------------------------------------------------------
(The Command Line)
7 $
opts4 -x
Please enter an argument after the -x option
usage: opts4 [-x] filename
2
8 $
opts4 -x filex
filex is the name of the argument
3
9 $
opts4 -d
d is not a valid option.
usage: opts4 [-x] filename
1
EXPLANATION
-
The alias
USAGE
is assigned the diagnostic error message that will be printed if
getopts
fails.
-
The
while
command tests the exit status of
getopts
; if
getopts
can successfully process an argument, it returns zero exit status, and the body of the
while
loop is entered. The colon prepended to the
x
option tells
getopts
not to print an error message if the user enters an invalid option. The colon appended to the
x
option tells
getopts
that an argument should follow the
x
option. If the option takes an argument, the argument is stored in the
getopts
built-in variable,
OPTARG
.
-
If the
x
option was given an argument, the argument is stored in the
OPTARG
variable and will be printed.
-
If an argument was not provided after the
x
option, a colon is stored in the variable
arguments
. The appropriate error message is displayed.
-
If an invalid option is entered, the question mark is stored in the variable
arguments
and an error message is displayed.
-
The special
getopts
variable,
OPTIND
, holds the number of the next option to be processed. Its value is always one more than the actual number of command-line arguments.
-
The
x
option requires an argument. An error message is printed.
-
The name of the argument is
filex
. The variable
OPTARG
holds the name of the argument
filex
.
-
The option
d
is invalid. The usage
message
is displayed.
|