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.
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
Copyright © 2003 O'Reilly & Associates. All rights reserved.