Handling Arguments with while and shift (Unix Power Tools, 3rd Edition)
35.22. Handling Arguments with while and shift
A for
loop (Section 35.21) is great if you want
to handle all of the command-line arguments to a script, one by one.
But, as is often the case, some arguments are options that have their
own arguments. For example, in the command grep -f
filename,
filename is an argument to
-f; the option and its argument need to be
processed together. One good way to handle this is with a combination
of while (Section 35.15), test (Section 35.26), case (Section 35.10), and shift.
Here's the basic construct:
while [ $# -gt 0 ]
do
case "$1" in
-a) options="$options $1";;
...
-f) options="$options $1"
argfile="$2"
shift
;;
*) files="$files $1";;
esac
shift
done
The trick is
this: shift removes an argument from the
script's argument list, shifting all the others over
by one ($1 disappears, $2
becomes $1, $3 becomes
$2, and so on). To handle an option with its own
argument, do another shift. The
while loop uses test (Section 35.26) to check
that $# -- the number of arguments -- is
greater than zero and keeps going until this is no longer true, which
only happens when they have all been used up.
Meanwhile, all the
case has to do is to test $1
against the desired option strings. In the simple example shown
above, we simply assume that anything beginning with a minus sign is
an option, which we (presumably) want to pass on to some program that
is being invoked by the script. So all we do is build up a shell
variable that will eventually contain all the options. It would be
quite possible to do something else instead, perhaps setting other
shell variables or executing commands.
We assume that anything without a minus sign is a file. This last
case could be written more robustly with a test to
be sure the argument is a file. Here's an example of
a simple script that uses this construct to pass an option and some
files to pr and from there to a program that
converts text to PostScript and on to the print spooler (or you could
convert SGML or XML files to PDF, whatever):
while [ $# -ne 0 ]
do
case $1 in
+*) pages="$1" ;;
*) if [ -f "$1" ]; then
files="$files $1"
else
echo "$0: file $1 not found" 1>&2
fi;;
esac
shift
done
pr $pages $files | psprint | lpr
This
approach is perhaps obsolete if you have getopts (Section 35.24)
(it's built into bash, for
instance), since getopts lets you recognize option
strings like -abc as being equivalent to
-a -b -c, but I still find it handy. [In this
example, it's essential. The pr
option +page-list starts with a plus sign.
getopt and getopts
don't support those old-style options.
-- JP]
--TOR and SJC
35.21. Handling Command-Line Arguments with a for Loop35.23. Loop Control: break and continue
Copyright © 2003 O'Reilly & Associates. All rights reserved.
Wyszukiwarka
Podobne podstrony:
ch35ch35!ch35ch35CH35 (4)ch35CH35ch35ch35ch35ch35ch35ch35ch35&ch35#ch35ch35więcej podobnych podstron