If you're running a shell script and you press your (like CTRL-c), the shell quits right away. That can be a problem if you use temporary files in your script because the sudden exit might leave the temporary files there. The trap command lets you tell the shell what to do before it exits. A trap can be used for a normal exit, too. See Table 44.1.
Here's a script named zpg that uses a temporary file named
/tmp/zpg$$ in a
The shell will replace
$$ with its
Because no other process will have the same ID number, that file
should have a unique name.
the file named on its command line, then starts the
pg file viewer.
The script uses traps - so it will clean up the temporary files,
even if the user
The script also sets a default exit status of 1 that's reset to 0 if
on its own (without an interrupt).
 The script could run
gzcat $1 | pgdirectly, but some versions of pg can't back up when reading from a pipe.
#!/bin/sh # zpg - UNCOMPRESS FILE, DISPLAY WITH pg # Usage: zpg file 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 case $# in 1) gzcat "$1" >$temp pg $temp stat=0 ;; *) echo "Usage: `basename $0` filename" 1>&2 ;; esac
There are two traps in the script:
The first trap, ending with the number
0, is executed for all shell
exits - normal or interrupted.
It runs the command line between the single quotes.
In this example, there are two commands separated with a
The first command
removes the temporary file (using the
so rm won't
give an error message if the file doesn't exist yet).
The second command exits with the value stored in the stat shell
Look ahead at the rest of the script-
$stat will always be 1 unless
the pg command quit on its own, in which case stat will be reset
Therefore, this shell script will always return the right exit status - if it's
interrupted before it finishes, it'll return 1; otherwise, 0.
 It's important to use single quotes, rather than double quotes, around the trap. That way, the value of
$statwon't be interpreted until the trap is actually executed when the script exits.
The second trap has the numbers
15 at the end.
These are signal numbers that correspond to different kinds of interrupts.
On newer shells, you can use signal names instead of the numbers.
There's a short list
For a list of all signals, type
kill -l (lowercase "L")
or see your online signal(3) reference page.
This trap is done on an abnormal exit (like CTRL-c). It prints a message, but it could run any list of commands.
|Signal Number||Signal Name||Explanation|
|1||HUP||When session disconnected|
|2||INT||Interrupt - often CTRL-c|
|3||QUIT||Quit - often CTRL-\|
|15||TERM||From kill command|
I usually don't trap signal 3 (QUIT) in scripts that I use myself. That gives me an easy way to abort the script without springing the trap (removing temporary files, etc.). In scripts for general use, though, I usually do trap it.
Also, notice that the echo commands in the script have at the end. That tells the Bourne shell to put the output of the echo command on the standard error instead of the standard output. This is a good idea because it helps to make sure that errors come to your screen instead of being redirected to a file or down a pipe with the other standard output text. (In this particular script, that doesn't matter much because the script is used interactively. But it's a good habit to get into for all of your scripts.)
If your trap runs a series of commands, it's probably neater to call athan a list of commands:
funcname1 2 15