To write flexible shell scripts, you usually want to give them
command-line arguments.
As you've seen in
other articles (44.11, 44.12),
$1
holds the first command-line argument.
The Bourne shell can give you arguments through the ninth, $9
.
The Korn Shell and some other newer Bourne-type shells understand
${10}
for the tenth argument, and so on.
(Article
8.5
has an overview of the shell's command-line handling.)
If you've been reading this
series (44.1)
of articles in order, you saw the
zpg (44.12)
script that accepted just one command-line argument.
If you put "$@"
in a script, the shell will replace that string
with a
quoted (8.14)
set of the script's command-line arguments.
Then you can pass as many arguments as you want, including pathnames
with
unusual characters (23.11):
%zpg report memo "savearts/What's next?"
The third argument has a perfectly legal filename; we see more and more of them on our system - especially filesystems that are networked to computers like the Macintosh, where spaces and other "special" characters in filenames are common. Double-quoting all arguments through the script helps to be sure that the script can handle these unusual (but legal!) pathnames.
In this case, we want the arguments to be passed to the gzcat command. Let's change the zpg script to read:
gzcat "$@" >$temp
When the shell runs the script with the arguments shown above, the command line will become:
gzcat "report" "memo" "savearts/What's next?" >/tmp/zpg12345
NOTE: On some Bourne shells, if there are no command-line arguments, the
"$@"
becomes a single empty argument (46.7), as if you'd typed this:gzcat "" >/tmp/zpg12345In this case, the gzcat command would complain that it can't find a file. (Of course, in this script, the case would prevent this problem. But not all scripts test the number of arguments.)
On those shells, you can replace
"$@"
with${1+"$@"}
(45.12). That means that if$1
is defined,"$@"
should be used. A less-good fix is to replace"$@"
with$*
. It gives you an unquoted list of command-line arguments; that's usually fine but can cause trouble on pathnames with special characters in them.
A
for loop (44.16)
can step through all command-line arguments, one by one.
You can also use a
while loop (44.10)
that tests $#
(see later in this chapter)
and removes the arguments one by one with the
shift command (44.17).
The
getopt and getopts (44.18)
commands handle arguments in a more standard way.
The $#
parameter counts the number of command-line arguments.
For instance, if there are three arguments, $#
will contain 3
.
This is usually used for error-checking
(as in the zpg script in article
44.12)
with
case (44.5)
or
test (44.20).
-