Kill: The Command to End All Commands
Linux is a powerful operating system. With its demand-paged memory management and swap file facility, it lets you start as many processes as you choose. Of course, that number is subject to overall system memory capacity (physical memory plus swap) and your CPU's ability to perform all the tasks you have requested. Starting processes is easy, and when things slow to a crawl, stopping them is just as easy.
The Linux kill command is one of two that will meet your need when you grow tired of waiting for a process to terminate. With it, you can, in the words of my 1992 Linux Programmer Manual, terminate a process with extreme prejudice. All you need to know is a number called the process PID. Note that kill doesn't always terminate another process. In essence, kill sends a signal to a specified process. If that signal is not caught and handled by the process (not all can be), the process is terminated. All of the resources that were in use by the process are released for use by other running processes.
What are processes, PIDs and signals? How are they discovered?
Recall that Linux is a multi-tasking operating system. When Linux boots, it starts a program called init, which in turn starts other programs. Many of these are background tasks like update, which periodically flushes data to the disk. Another example is getty, which watches a serial port for some sign of activity. A more visible example is the shell you use to perform useful work. It runs in the foreground, which means that it waits on your keystrokes. Each copy of each program running on your system is called a process.
Just as the US government passes out Social Security Numbers (we use Social Insurance Numbers here in Canada) to uniquely identify each individual, Linux assigns each process a unique number as an identifier. This number is called the process ID or PID.
When a process is started, it is given the next available PID, and when it terminates, its PID is released for eventual re-use. To determine the PID of any process belonging to you, enter ps at the prompt. The ps command will print, for each of your processes, a line containing the process's PID, the amount of time the process has used and the command with which the process was started. The output from ps looks like:
PID TT STAT TIME COMMAND 6651 p0 S 0:01 -ksh<\n> 6661 p1 S 0:00 -ksh 6738 p2 S 0:00 -ksh 6746 p2 S 0:00 wheel 6747 p2 S 0:00 wheel 7002 p0 S 0:01 elm 7193 p1 R 0:00 ps
Signals are a form of process communication. Because they can come from another process, the kernel or the process itself, they might be better thought of as events that occur as a program runs. A crude example might be the bell most of us remember from our early days in school; when the bell rang, we reacted by switching from playful children to industrious students.
The signals we will use below are the termination signal SIGTERM, the interrupt signal SIGINT and the kill signal SIGKILL. These signals usually occur because another process sent them. You probably already use one of them; typing ctrl-c sends the interrupt signal SIGINT to your current foreground process. Other signals—such as SIGPIPE, which is sent to a process writing to a broken pipe—usually come from the kernel. There are about 30 signals, all of which can be referred to by numbers or by names, but the numbers change between platforms and some signals are unavailable on some platforms. The complete list of signals can be found on the signal(7) manual page; enter man 7 signal to see it or enter kill -1 for a short version of this list.
For each signal there is a default action, almost all of which terminate the process. For most signals, a program may specify another action—this is called catching or handling the signal—or may specify that no action occurs, which is called ignoring the signal. The signal SIGKILL cannot be caught or ignored; it always terminates processes.
For example, suppose you use cat to list a large text file without first determining the size of the file. Instead of watching hundreds, perhaps thousands of lines scroll by too quickly to read, you send the cat process the interrupt signal by pressing Ctrl-c. Fortunately, cat was not programmed to catch SIGINT, and the cat process is terminated immediately.
Suppose we had inadvertently started cat in the background; Ctrl-c would be ineffective, because the signal wouldn't get to the cat process. So we need to send it a signal some other way. With the command kill, you can send any signal to any process you own. The command's syntax is:
If no signal is specified on the kill command line, the terminate signal SIGTERM (default) is sent. This will normally terminate the process in question. If it fails to do so—that is, SIGTERM was caught or ignored—you can send the signal SIGKILL, which will always terminate the process.
Thus, we might do the following to terminate our runaway cat process commands. First determine the PID:
$ ps PID TT STAT TIME COMMAND 2037 p0 S 0:01 cat
Now, kill process 2037, which is the cat process:
kill 20371If cat had been written to catch SIGTERM, we would have to use a signal that cannot be caught or ignored.
kill -SIGKILL 20371In addition to killing errant processes, kill can be used to inform processes that the status of something has changed. For example, suppose you are writing a program and you wish to have it change its mode of operation on the occurrence of some external event. By coding what is called an “interrupt handler” in your program, you can have it catch any number of signals which have meaning to you. In particular, you might choose SIGUSR1 or SIGUSR2, which are non-specific. By sending your chosen signal, you can make your program aware of the change in circumstances, so it can proceed into its alternate mode of operation.
When you use kill, the desired signal is sent only to processes you own (that is, processes that you invoked). This prevents inadvertent termination of the wrong process. The exception is that the superuser (root) can use kill to send a signal to any process. Similarly, any process owned by root can send a signal to any other process.
An orderly shutdown of your system can occur in this way. While the kill command is not used at shutdown, the equivalent system call kill(2) is used to terminate everything. This guarantees that no files are left open and that all buffers are written to disk. For a description of kill(2), enter man 2 kill at the prompt.
A related command is killall, which takes the name of the process as an argument rather than the process ID (PID). (Some versions of kill can take process names too.) This is a convenient way to terminate all processes with the same name. If a path is used to identify the process to be signaled, only the processes executing that particular file are selected. In addition, you can ask to be consulted before killall kills a particular process, and you can receive confirmation that the signal was actually sent.
Although full details are listed in the man page, an example may be useful here. Suppose you have two programs that are different but have the same name—perhaps different release levels. In order to be different and have the same name, they must be stored in different directories. Assume they have the name sample_prog, but one is stored in /usr/a and the other in /usr/b. Entering ps gives the following output:
PID TTY STAT TIME COMMAND 123 pp0 S 0:03 /usr/a/sample_prog 124 pp1 R 0:02 /usr/b/sample_prog
The following commands perform different actions:
# To kill both processes killall sample_prog # To kill only process 123 killall /usr/a/sample_prog
In summary, the kill and killall commands can be useful tools to control the execution of processes on your Linux system. In combination with other tools described in previous “Take Command” columns, they will allow you to become true masters of a very powerful desktop appliance. For specific information on their very few options, and for a description of the signals they can invoke, read the relevant manual pages (enter man kill or man killall at the prompt).