Most shell scripts understand command-line parameters and interact with the commands that they run. To take your scripts from simple lists of commands to more flexible programs, you need to know how to use the special Bourne shell variables. Using special variables is not much different than using any other shell variable (see Section 1.8), but you cannot change the value of certain special variables.
After reading the next few sections, you will understand why shell scripts accumulate many special characters as they are written. If you're trying to understand a shell script and you come across a line that looks completely incomprehensible, pick it apart piece by piece.
$1, $2, and all variables named as positive nonzero integers contain the values of the script parameters, or arguments.
Let's say the name of the following script is named pshow:
#!/bin/sh echo First argument: $1 echo Third argument: $3
Running pshow one two three produces this output:
First argument: one Third argument: three
The built-in shell command shift is used with argument variables. This command removes the first argument ($1) and advances the rest of the arguments forward — that is, $2 becomes $1, $3 becomes $2, and so on. Assume that the name of the following script is shiftex:
#!/bin/sh echo Argument: $1 shift echo Argument: $1 shift echo Argument: $1 shift
Run shiftex one two three. This output appears:
Argument: one Argument: two Argument: three
The $# variable holds the number of arguments passed to the script. This variable is especially important when running shift in a loop to pick through arguments; when $# is 0, no arguments remain, so $1 is empty. (See Section 7.6 for a description of loops.)
The $@ variable represents all of the script's arguments, and it is very useful for passing all of a script's arguments to one of the commands inside the script. For example, you will learn in Section 12.6 that the arguments to Ghostscript (gs) are complicated. Suppose that you want a shortcut for rasterizing a PostScript file at 150 dpi, using the standard output stream, but also leaving the door open for passing other options to gs. You could write a script like the following that allows for additional command-line options:
#!/bin/sh gs -q -dBATCH -dNOPAUSE -dSAFER -sOutputFile=- -sDEVICE=pnmraw $@
If a line in your shell script gets too long for your text editor, you can split it up with a backslash (\). For example, you can alter the preceding script as follows:
#!/bin/sh gs -q -dBATCH -dNOPAUSE -dSAFER \ -sOutputFile=- -sDEVICE=pnmraw $@
A double-quoted $@ ("$@") expands to the parameters separated by spaces.
The $0 variable holds the name of the script, and it is useful for generating diagnostic messages. Let's say that your script needs to report an invalid argument that is stored in the $BADPARM variable. You can print the diagnostic message with the following line so that the script name appears in the error message:
echo $0: bad option $BADPARM
You should send diagnostic error messages to the standard error. Recall from Section 1.14.1 that 2>&1 redirects the standard error to the standard output. For writing to the standard error, you can reverse the process with 1>&2. To do this for the preceding example, use this:
echo $0: bad option $BADPARM 1>&2
The $$ variable holds the process ID of the shell.
The $? variable holds the exit code of the last command that the shell executed. Exit codes are critical to mastering shell scripts, and they're discussed next.