Unix Power Tools
Handling Command-Line Arguments with a for Loop
by Jerry Peek
02/10/2000
Sometimes you want a script that will step through the command-line arguments
one by one.
(The
$@ parameter
gives you all of them at once.)
The Bourne shell for loop can do this.
The for loop looks like this:
for arg in list
do
...handle $arg...
doneIf you omit the in list, the loop steps through the command-line arguments.
It puts the first command-line argument in arg (or whatever
else you choose to call the
shell variable),
then executes the commands from do to done.
Then it puts the next command-line argument in arg, does the loop...
and so on... ending the loop after handling all the arguments.
For an example of a for loop, let's hack on the
the zpg
script.
#!/bin/sh
# zpg - UNCOMPRESS FILE(S), DISPLAY WITH pg
# Usage: zpg [pg options] file [...files]
stat=1 # DEFAULT EXIT STATUS; RESET TO 0 BEFORE NORMAL EXIT
temp=/tmp/zpg$$
trap 'rm -f $temp; exit $stat' 0
trap 'echo "`basename $0`: Ouch! Quitting early..." 1>&2' 1 2 15
files= switches=
for arg
do
case "$arg" in
-*) switches="$switches $arg" ;;
*) files="$files $arg" ;;
esac
done
case "$files" in
"") echo "Usage: `basename $0` [pg options] file [files]" 1>&2 ;;
*) for file in $files
do gzcat "$file" | pg $switches
done
stat=0
;;
esacWe added a for loop to get and check each command-line argument.
For example, let's say that a user typed:
The first pass through the for loop, $arg is -n.
Because the argument starts with a minus sign (-),
the case treats it as an option.
Now the switches variable is replaced by its previous contents
(an empty string), a space, and -n.
Control goes to the esac and the loop repeats
with the next argument.
The next argument, afile, doesn't look like an option.
So now the files variable will contain a space and afile.
The loop starts over once more, with ../bfile in $arg.
Again, this looks like a file, so now $files has
afile ../bfile.
Because ../bfile was the last argument, the loop ends;
$switches
has the options and $files has all the other arguments.
Next, we added another for loop.
This one has the word in followed by $files,
so the loop steps through the contents of $files.
The loop runs gzcat on each file, piping it to pg with any switches
you gave.
Note that $switches isn't
quoted.
This way, if $switches is empty, the shell won't pass an empty
argument to pg.
Also, if $switches has more than one switch, the shell will break the
switches into separate arguments at the spaces and pass them individually to
pg.
You can use a for loop with any space-separated (actually,
IFS-separated)
list of words -- not just filenames.
You don't have to use a shell variable as the list;
you can use command substitution (backquotes),
shell wildcards,
or just "hardcode" the list of words:
for person in Joe Leslie Edie Allan
do
echo "Dear $person," | cat - form_letter | lpr
done
More Unix Power Tools