pid="$pid $!"
job3 &
pid="$pid $!"
trap "kill -15 $pid" 0 1 2 15
wait
$? - error status
The "$?" variable is equal to the error return of the previous program. You can remember this variable, print it
out, or perform different actions based on various errors. You can use this to pass information back to the
calling shell by exiting a shell script with the number as an argument. Example:
#!/bin/sh
# this is script1
exit 12
Then the following script
#!/bin/sh
script1
echo $?
would print 12.
$- Set variables
The variable "$-" corresponds to certain internal variables inside the shell. I'll discuss this next.
Options and debugging
The Bourne Shell set command is somewhat unusual. It has two purposes: setting certain shell options, and
setting positional parameters. I mentioned positional parameters earlier. These are the arguments passed to a
shell script. You can think of them as an array, of which you can only see the first nine values, by using the
special variables $1 through $9. As I mentioned earlier, you can use the shift command to discard the first
one, and move $2 to $1, etc. If you want to see all of your variables, the command
set
will list all of them, including those marked for export. You can't tell which ones are marked. But the external
command env will do this.
You can also explicitly set these variables, by using the set command. Therefore the Bourne shell has one
array, but only one. You can place anything in this array, but you lose the old values. You can keep them,
however, by a simple assignment:
old=$@
set a b c
# variable $1 is now equal to "a", $2=b, and $3=c
Bourne Shell Tutorial
http://www.grymoire.com/Unix/Sh.html
29 of 66
11/21/2011 12:03 PM
set $old
# variable $1 now has the original value, as does $2, etc.
This isn't perfect. If any argument has a space inside, this information isn't retained. That is, if the first
argument is "a b," and the second is "c," then afterwards the first argument will be "a," the second "b," and
the third "c." You may have to explicitly handle each one:
one=$1;two=$2;three=$3
set a b c
# argument $1 is "a", etc.
set "$one" "$two" "$three"
# argument $1, $2 and $3 are restored
If you wanted to clear all of the positional parameters, try this:
set x;shift
Special options
As you recall, the dollar sign is a special character in the Bourne shell. Normally, it's used to identify
variables. If the variable starts with a letter, it's a normal variable. If it starts with a number, it's a positional
parameter, used to pass parameters to a shell script. Earlier, I've discussed the $*, $@, $#, $$, and $! special
variables. But there are another class of variables, or perhaps the proper term is flags or options. They are not
read. That is, you don't use them in strings, tests, filenames, or anything like this. These variables are boolean
variables, and are internal to the shell. That is, they are either true or false. You cannot assign arbitrary values
to them using the "=" character. Instead, you use the set command. Also, you can set them and clean them,
but you cannot read them. At least, not like other variables. You read them by examining the "$-" variable,
which shows you which ones are set.
Excuse me, but I am going to fast. I'm teaching you how to run, before I explained walking. Let's discuss the
first flag, and why it's useful.
X - Bourne Shell echo flag
If you are having trouble understanding how a shell script works, you could modify the script, adding echo
commands so you can see what is happening. Another solution is to execute the script with the "x" flag. There
are three ways to set this flag. The first, and perhaps easiest, is to specify the option when executing the
script: To demonstrate, assume the file script is:
#!/bin/sh
a=$1
echo a is $a
Then
if you type
sh -x script abc
the script will print out
a=abc
Bourne Shell Tutorial
http://www.grymoire.com/Unix/Sh.html
30 of 66
11/21/2011 12:03 PM
+ echo a is abc
a is abc
Notice that built-in commands are displayed, while external commands are displayed with a "+" before each
line. If you have several commands separated by a semicolon, each part would be displayed on its own line.
The "x" variable shows you each line before it executes it. The second way to turn on this variable is to
modify the first line of the script, i.e.:
#!/bin/sh -x
As you can see, the first way is convenient if you want to run the script once with the variable set, while the
second is useful if you plan to repeat this several times in a row. A large and complex script, however, is
difficult to debug when there are hundreds of lines to watch. The solution is to turn the variable on and off as
needed, inside the script. The command
set -x
turns it on, while
set +x
turns the flag off again. You can, therefore, turn the "echo before execute" flag on or off when convenient.
V - Bourne Shell verbose flag
A similar flag is the "v," or verbose flag. It is also useful in debugging scripts. The difference is this: The "v"
flag echoes the line as it is read, while the "x" flag causes each command to be echoed as it is executed. Let's
examine this in more detail. Given the script:
#!/bin/sh
# comment
a=${1:-`whoami`};b=${2:-`hostname`}
echo user $a is using computer $b
typing "sh -x script" causes:
+ whoami
a=barnett
+ hostname
b=grymoire
+ echo user barnett is using computer grymoire
user barnett is using computer grymoire
However, "sh -v script" reports
#!/bin/sh
# comment
a=${1:-`whoami`};b=${2:-`hostname`}
echo user $a is using computer $b
user barnett is using computer grymoire
Bourne Shell Tutorial
http://www.grymoire.com/Unix/Sh.html
31 of 66
11/21/2011 12:03 PM