How to send signals to processes with kill in Linux

Signals

Linux (and Unix) uses signals to notify processes of abnormal events, and as a primitive mechanism of interprocess communication. Signals are sometimes referred to as software interrupts, in that they can interrupt the normal flow of execution of a process. The kernel uses signals to notify processes of abnormal behavior, such as if the process tries to divide a number by zero, or tries to access memory that does not belong to it.

Processes can also send signals to other processes. For example, a bash shell could send a signal to an xclock process. The receiving process knows very little about the origins of the signal. It doesn’t know if the signal originated from the kernel, or from another process; all it knows is that it received a signal.

xclock receiving a signal number 15 from bash

There are, however, different flavors of signals. The different flavors have symbolic names, but are also identified by integers. The various integers, and the symbolic name they are mapped to, can be listed using the kill -l command, or examined in the signal man page.

# kill -l
 1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP
 6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM
16) SIGSTKFLT	17) SIGCHLD	18) SIGCONT	19) SIGSTOP	20) SIGTSTP
21) SIGTTIN	22) SIGTTOU	23) SIGURG	24) SIGXCPU	25) SIGXFSZ
26) SIGVTALRM	27) SIGPROF	28) SIGWINCH	29) SIGIO	30) SIGPWR
31) SIGSYS	34) SIGRTMIN	35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3
38) SIGRTMIN+4	39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12	47) SIGRTMIN+13
48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14	51) SIGRTMAX-13	52) SIGRTMAX-12
53) SIGRTMAX-11	54) SIGRTMAX-10	55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7
58) SIGRTMAX-6	59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2
63) SIGRTMAX-1	64) SIGRTMAX

Linux, like most versions of Unix, implements 32 “normal” signals. In Linux, signals numbered 32 through 64 (which are not standard among the various versions of Unix) are “real time” signals.

Why Are Signals Sent?

There are a variety of reasons why signals might be sent to a process, as illustrated by the following examples.

Hardware Exceptions

The process asked the hardware to perform some erroneous operation. For example, the kernel will send a process a SIGFPE (signal number 8) if it performs a divide by 0.

Software Conditions

Processes may need to be notified of some abnormal software condition. For example, whenever a process dies, the kernel sends a SIGCHLD (signal number 17) to the process’s parent. As another example, X graphical applications receive a SIGWINCH (signal number 28) whenever their window is resized, so that they can respond to the new geometry.

Terminal Interrupts

Various terminal control key sequences send signals to the bash shell’s foreground process. For example, CTRL-C sends a SIGINT (signal number 2), while CTRL-Z sends a SIGTSTP (signal number 20).

Other Processes

Processes may elect to send any signals to any other process which is owned by the same user. The kill command is designed to do just this.

Sending Signals: the kill Command

The kill command is used to deliver custom signals to other processes. It expects to be called with a numeric or symbolic command line switch, which specifies which signal to send, and a process ID, which specifies which process should receive it. As an example, the following commands deliver a SIGCHLD (signal number 17) to the xclock process, process ID number 8060.

$ ps
 PID  TTY    TIME      CMD
7985  pts/5  00:00:00  bash
8060  pts/5  00:00:01  xclock
8061  pts/5  00:00:00  ps
$ kill -17 8060
$ kill -CHLD 8060
$ kill -SIGCHLD 8060

When using the symbolic name to specify a signal, the “SIG” prefix (which all signals share) can either be included or omitted.

Receiving Signals

When a process receives a signal, it may take one of the following three actions.

1. Implement a Kernel Default Signal Handler

For each type of the signal, there is a default response which is implemented by the kernel. Each signal is mapped to one of the following behaviors.

  • Terminate: The receiving process is killed.
  • Ignore: The receiving process ignores the signal
  • Core: The receiving process terminates, but first dumps an image of its memory into a file named core in the process’s current working directory. The core file can be used by developers to help debug the program.
  • Stop: Stop (suspend) the process.

The “signal” man page documents which behavior is mapped to which signal.

2. Choose to Ignore the Signal

Programmers may elect for their application to simply ignore specified signals.

3. Choose to Implement a Custom Signal Handler

Programmers may elect to implement their own behavior when a specified signal is received. The response of the program is completely determined by the programmer. Unless a program’s documentation says otherwise, you can usually assume that a process will respond with the kernel implemented default behavior. Any other response should be documented.

Using Signals to Terminate Processes

Of the 32 signals used in Linux (and Unix), standard users in practice only (explicitly) make use of a few.

Number Symbol Action
2 SIGINT Interrupt (request termination) of the process. This is the signal generated by the CTRL-C control sequence.
9 SIGKILL Force termination of the process (This signal may not be overridden by the process).
15 SIGTERM Request Termination of the process.
20 SIGTSTP Stop (suspend) the process. This is the signal generated by the CTRL-Z control sequence.

Usually, standard users are using signals to terminate a process (thus the name of the kill command). By convention, if programmers want to implement custom behavior when shutting down (such as flushing important memory buffers to disk, etc.), they implement a custom signal handler for signal number 15 to perform the action. Signal number 9 is handled specially by the kernel, and cannot be overridden by a custom signal handler or ignored. It is reserved as a last resort, kernel level technique for killing a process.

As an example, einstein will start a cat command that would in principle run forever. He then tracks down the process ID of the command, and terminates it with a SIGTERM.

$ cat /dev/zero > /dev/null &
[1] 8375
$ ps
 PID  TTY    TIME      CMD
7985  pts/5  00:00:00  bash
8375  pts/5  00:00:01  cat
8376  pts/5  00:00:00  ps
$ kill -15 8375
[1]+ Terminated            cat /dev/zero >/dev/null

SIGTERM (signal number 15) is the default signal for the kill command, so einstein could have used kill 8375 to the same effect. In the following, einstein repeats the sequence, this time sending a SIGKILL.

$ cat /dev/zero > /dev/null &
[1] 8387
$ ps
PID   TTY     TIME      CMD
7985  pts/5   00:00:00  bash
8387  pts/5   00:00:01  cat
8388  pts/5   00:00:00  ps
$ kill -9 8387
[1]+ Killed              cat /dev/zero >/dev/null

Using signals to control processes is such a common occurrence, alternatives to using the kill command abound. The following sections mention a few.

The pkill Command

In each of the previous examples, einstein needs to determine the process ID of a process before sending a signal to it with the kill command. The pkill command can be used to send signals to processes selected by more general means. The pkill command expects the following syntax.

pkill [-signal] [SWITCHES] [PATTERN]

The first token optionally specifies the signal number to send (by default, signal number 15). PATTERN is an extended regular expression that will be matched against command names. The following table lists commonly used command line switches. Processes that meet all of the specified criteria will be sent the specified signal.

Switch Effect
-n Select only the newest (most recently started) matching process.
-u USER Select processes owned by the user USER.
-t TERM Select processes controlled by terminal TERM.

Conveniently, the pkill command omits itself and the shell which started it when killing all processes owned by a particular user or terminal. Consider the following example.

$ ps
PID    TTY     TIME      CMD
10353  pts/4   00:00:00  bash
10396  pts/4   00:00:01  xclock
10397  pts/4   00:00:00  mozilla-bin
10422  pts/4   00:00:00  ps
$ pkill -u maxwell
[1]- Terminated           xclock
$ ps
PID    TTY     TIME      CMD
10353  pts/4   00:00:00  bash
10424  pts/4   00:00:00  ps
[2]+  Exit 15                    mozilla

Notice that, although the bash shell qualifies as a process owned by the user maxwell, it survived the slaughter.

The killall Command

Similar to pkill, the killall command delivers signals to processes specified by command name. The killall command supports the following command line switches.

Switch Effect
-i, –interactive Interactively query the user before delivering a signal to a process.
-w, –wait Wait until all processes are killed before returning.

The top Command

The top command can also be used to deliver signals to processes. Using the K key, the following dialog occurs above the list of processes, allowing the user to specify which process ID should receive the signal, and which signal to deliver.

PID to kill: 4859
Kill PID 4859 with signal [15]: 9