home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


UNIX Power Tools

UNIX Power ToolsSearch this book
Previous: 44.15 Handling Command-Line Arguments in Shell Scripts Chapter 44
Shell Programming for the Uninitiated
Next: 44.17 Handling Arguments with while and shift
 

44.16 Handling Command-Line Arguments with a for Loop

Sometimes you want a script that will step through the command-line arguments one by one. (The "$@" parameter (44.15 ) 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
...
done

If 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 (6.8 ) ), 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 zpg (44.12 ) script.











case
 












#!/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
    ;;
esac

We added a for loop to get and check each command-line argument. For example, let's say that a user typed:

% zpg -n afile ../bfile

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 (8.14 ) . 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 (35.21 ) -separated) list of words - not just filenames. You don't have to use a shell variable as the list; you can use command substitution (9.16 ) (backquotes), shell wildcards (15.2 ) , or just "hardcode" the list of words:


-
 lpr
 
for person in Joe Leslie Edie Allan

do
   echo "Dear $person," | cat - form_letter | lpr
done

The getopt and getopts (44.18 ) commands handle command-line arguments in a more standard way than for loops.

- JP


Previous: 44.15 Handling Command-Line Arguments in Shell Scripts UNIX Power Tools Next: 44.17 Handling Arguments with while and shift
44.15 Handling Command-Line Arguments in Shell Scripts Book Index 44.17 Handling Arguments with while and shift

The UNIX CD Bookshelf NavigationThe UNIX CD BookshelfUNIX Power ToolsUNIX in a NutshellLearning the vi Editorsed & awkLearning the Korn ShellLearning the UNIX Operating System