Trapping Exits Caused by Interrupts (Unix Power Tools, 3rd Edition)
35.17. Trapping Exits Caused by Interrupts
If you're running a shell script and you press
your interrupt key (Section 5.8)
(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 35-1.
Table 35-1. Some Unix signal numbers for trap commands
Signal number
Signal name
Explanation
0
EXIT
exit command
1
HUP
When session disconnected
2
INT
Interrupt -- often CTRL-c
3
QUIT
Quit -- often CTRL-\
9
KILL
Kill, often used as a way to stop an errant program (it cannot be
caught, so don't bother to trap it)
15
TERM
From kill command
Here's
a script named zmore that uses a temporary file
named /tmp/zmore$$ in a system temporary-file
directory. The shell will replace $$ with its
process ID number (Section 24.3). Because no other process will have the same
ID number, that file should have a unique name. The script uncompresses (Section 15.6)
the file named on its command line, then starts the
more file viewer.[107] The script uses traps, so
it will clean up the temporary files, even if the user presses
CTRL-c. The script also sets a default exit status of 1
that's reset to 0 if more quits
on its own (without an interrupt). If you are on a Linux system, you
may find that gzcat is simply named
zcat.
[107]The script could
run gzcat $1 | more directly, but some versions of
more can't back up when reading
from a pipe. You may prefer to use less, at any
rate.
exit Section 35.16
#!/bin/sh
# zmore - UNCOMPRESS FILE, DISPLAY WITH more
# Usage: zmore file
stat=1 # DEFAULT EXIT STATUS; RESET TO 0 BEFORE NORMAL EXIT
temp=/tmp/zmore$$
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
more $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 semicolon (;)
(Section 28.16). The first command removes the
temporary file (using the -f
option (Section 14.10), 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
variable. Look ahead at the rest of the
script -- $stat will always be 1 unless the
more command quit on its own, in which case
stat will be reset to 0. Therefore, this shell
script will always return the right exit status -- if
it's interrupted before it finishes,
it'll return 1; otherwise, 0.[108]
[108]It's important to use single quotes rather
than double quotes around the trap. That way, the
value of $stat won't be
interpreted until the trap is actually executed when the script
exits.
The
second trap has the numbers 1
2 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 in Table 35-1. For a list of all signals, type kill
-l (lowercase
"L") or see your online
signal(3) or signal(2)
manual page. Alternatively, look for a file named
/usr/include/signal.h or
/usr/include/linux/signal.h (which itself just
includes /usr/include/asm/signal.h, which is
where the constants themselves are defined).
This trap is done on an abnormal exit (like CTRL-c). It prints a
message, but it could run any list of commands.
Shell scripts don't always
have two traps. Look at the nom (Section 33.8) script for
an example.
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 1>&2 (Section 36.16) at
the end. This is the standard way to make error messages. 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 a shell function (Section 29.11)
than a list of commands:
trap funcname 1 2 15
--JP and SJC
35.16. Set Exit Status of a Shell 35.18. read: Reading from the Keyboard
Copyright © 2003 O'Reilly & Associates. All rights reserved.
Wyszukiwarka
Podobne podstrony:
ch35!ch35ch35CH35 (4)ch35CH35ch35ch35ch35ch35ch35ch35ch35ch35&ch35#ch35ch35więcej podobnych podstron