sections in this module City College of San Francisco - CS260A
Linux System Administration

Module: Processes
module list

signals and traps

A signal is used to interrupt a process and get it to perform an action. Everyone has used signals - the control-C key on the keyboard generates a signal. While the majority of signals that are sent to a process are fatal, this is not necessarily the case.

Sources of signals

Signals can come from a variety of sources:

kill [-SIG] N

Here, SIG is a signal number or a standard signal name (see below), and N is a pid, or, in the case of a shell with a builtin kill, a job number prefixed by %. N also has a few special values:

if N is 0, the signal is sent to all processes in the current process group

if N is -1, kill attempts to send the signal to every process on the system (i.e., 'signal every process that you can'). The only exception is init. If N is -1, the signal must be specified.

if N is otherwise negative and N is the pid of a process group leader, the signal is sent to every process in the process group. Again, the signal must be specified to avoid ambiguity between the signal number and target of the signal.

Signal numbers and names

Signal names are standardized, although some implementations may have additional signals. The signal numbers, except for those noted, are not standard. If you need to know a signal number, use kill -l (thats lower-case L) to get a list of signal numbers and names. 

signal name signal number
(if standard)
meaning
HUP 1 hangup or disconnect. may be sent to children of an interactive shell if the shell user logs off
HUP is also used by daemons to force reconfiguration.
INT 2 interrupt (usually mapped to key control-C)
QUIT 3 quit
KILL 9 uncatchable kill signal
TERM 15 software terminate. This is the default signal sent by kill if no signal is specified on the kill command.
STOP
uncatchable stop
TSTP
suspend
CONT
continue if stopped
SEGV/BUS/ILL
kernel-generated faults
USR1/USR2
reserved for the user

When specifying a signal to kill, either the number or the name may be used. If the name is used, it may be prefixed with SIG. For example

kill -15 4287

kill -TERM 4287

kill -SIGTERM 4287

kill 4287

all send the TERM signal to pid 4287

What happens when a signal is received

Each signal has a specified default action. This action is taken unless the process specifies otherwise. In most cases, the default action is terminate, possibly with a core file. (A core file is a memory dump of the program when the fault (signal) occurred. It is used by programmers to debug the program.)

Most signals allow a process to 'handle' (catch) or to ignore the signal. The exceptions are the signals KILL, STOP and CONT, which cannot be caught or ignored, and always trigger the default action. If a signal is caught, the handler may change the signal handling for next time. Besides these three signals, all other signals allow the process to specify to

The manual page on signal(7) specifies the default action for each signal. You must specify the section number since signal is also the name of a C library function.

Propagation of signals

If the shell receives a signal, that signal is usually propagated to its foreground and suspended children. This kind of makes sense, as these children are 'dependent' on the shell. 

Normally, signals sent to the shell are not propagated to the shell's running background children, as these children are considered 'independent'. One notable exception is the HUP signal, which is sent to the shell if it is disconnected. If you want to ensure that your background process is protected if your shell is disconnected, you should prefix the command with nohup. For example, the following make will continue even if the shell that started it is disconnected.

nohup make > make.out 2>&1 &

traps

Shell scripts can specify what happens upon receipt of a signal by use of the trap command

trap 'command'  list-of-signals

Here, list-of-signals is a list of signal numbers or signal names similar to kill(1). 

If command is empty (an empty command, indicated by a set of empty quotes), the signals are ignored.

If command does not exist or is a dash, the default action is restored for future instances of each of the signals.

If command is a Unix command, which could also be a function call, where the function is defined in the current shell program, the command is installed as the signal handler and is executed upon receipt of the signal. The 'command' is not interpreted until the signal occurs, so standard quoting rules can produce differing results. 

Suppose we had a shell program that processed files and counted how many files had been processed, keeping the count in $COUNT. The two traps

trap 'echo $COUNT files processed' TERM

trap "echo $COUNT files processed" TERM

would give very different results when the TERM signal is encountered. The first would substitute the value of $COUNT at the time the signal occurs (the time the trap was sprung), since the single-quotes delay the expansion of $COUNT until then. The second would substitute the value of $COUNT at the time the trap command is processed (e.g., at the time the trap was set)

The EXIT trap

It is often desirable to perform an action any time the shell script exits for any reason. The special pseudo-signal EXIT can be used in a trap command to do just this. EXIT is not a signal: it simply triggers the associated trap upon exit of the shell script.

The EXIT trap is sprung whenever the shell script exits under its own control - normal exit or exit due to a signal. It is not sprung, however, if the shell script exits due to a signal that is uncatchable such as KILL.

A historical restriction of the EXIT trap was that it must be first trap to appear in the program. Thus, as the program is executed, the EXIT trap should be set first. Normally, all traps are set before other executable code in the shell script is encountered, i.e., at the beginning of the shell script.

Example

The following few lines of a shell script output a message and exit on receipt of INT and TERM, and invoke a shell function on receipt of the signal WINCH. The shell script also removes its temporary file when it exits for any reason. Cut and paste it to a file and run it. Then resize the window. You might want to look up what tput does.

#!/bin/bash
tmpfile=/tmp/$$.tmp
echo $LOGNAME > $tmpfile
trap 'rm -f $tmpfile' EXIT
trap 'echo interrupt; exit' INT
trap 'echo terminated >&2; exit' TERM
trap 'resize' WINCH
resize() {

echo "WINCH: COLS=$(tput cols); LINES=$(tput lines)"
}
while : ; do
:
done


Prev This page was made entirely with free software on linux:  
Kompozer, the Mozilla Project
and Openoffice.org    
Next

Copyright 2014 Greg Boyd - All Rights Reserved.