Библиотека сайта rus-linux.net
12.2. Traps
12.2.1. General
There might be situations when you don't want users of your scripts to exit untimely using keyboard abort sequences, for example because input has to be provided or cleanup has to be done. The trap statement catches these sequences and can be programmed to execute a list of commands upon catching those signals.
The syntax for the trap statement is straightforward:
trap [COMMANDS] [SIGNALS]
This instructs the trap command to catch the listed SIGNALS, which may be signal names with or without the SIG prefix, or signal numbers. If a signal is 0 or EXIT, the COMMANDS are executed when the shell exits. If one of the signals is DEBUG, the list of COMMANDS is executed after every simple command. A signal may also be specified as ERR; in that case COMMANDS are executed each time a simple command exits with a non-zero status. Note that these commands will not be executed when the non-zero exit status comes from part of an if statement, or from a while or until loop. Neither will they be executed if a logical AND (&&) or OR (||) result in a non-zero exit code, or when a command's return status is inverted using the ! operator.
The return status of the trap command itself is zero unless an invalid signal specification is encountered. The trap command takes a couple of options, which are documented in the Bash info pages.
Here is a very simple example, catching Ctrl+C from the user, upon which a message is printed. When you try to kill this program without specifying the KILL signal, nothing will happen:
#!/bin/bash # traptest.sh trap "echo Booh!" SIGINT SIGTERM echo "pid is $$" while : # This is the same as "while true". do sleep 60 # This script is not really doing anything. done |
12.2.2. How Bash interprets traps
When Bash receives a signal for which a trap has been set while waiting for a command to complete, the trap will not be executed until the command completes. When Bash is waiting for an asynchronous command via the wait built-in, the reception of a signal for which a trap has been set will cause the wait built-in to return immediately with an exit status greater than 128, immediately after which the trap is executed.
12.2.3. More examples
12.2.3.1. Detecting when a variable is used
When debugging longer scripts, you might want to give a variable the trace attribute and trap DEBUG messages for that variable. Normally you would just declare a variable using an assignment like VARIABLE
=value. Replacing the declaration of the variable with the following lines might provide valuable information about what your script is doing:
declare -t VARIABLE=value trap "echo VARIABLE is being used here." DEBUG # rest of the script |
12.2.3.2. Removing rubbish upon exit
The whatis command relies on a database which is regularly built using the makewhatis.cron
script with cron:
#!/bin/bash LOCKFILE=/var/lock/makewhatis.lock # Previous makewhatis should execute successfully: [ -f $LOCKFILE ] && exit 0 # Upon exit, remove lockfile. trap "{ rm -f $LOCKFILE ; exit 255; }" EXIT touch $LOCKFILE makewhatis -u -w exit 0 |