There's more than one way to kill a Unix process

halt jochen spalding
Credit: Jochen Spalding

Terminating processes on Unix systems is not quite an art, but there are sure a lot more options for how to select and terminate Unix processes than there are ways to skin a cat. In this post, we take a quick look at some of the commands and options that are likely to be the most useful.

Control sequences

The most obvious way to kill a process is probably to type Ctrl-C. This assumes, of course, that you've just started running it and that you're still on the command line with the process running in the foreground. There are other control sequence options as well. You could suspend a process by using Ctrl-Z and then running a command such a kill %1 (depending on how many background processes you have running) to snuff it out.

  • Ctrl-C sends SIGINT (interrupt)
  • Ctrl-Z sends TSTP (terminal stop)
  • Ctrl-\ sends SIGQUIT (terminate and dump core)
  • Ctrl-T sends SIGINFO (show information), but this sequence is not supported on all Unix systems

Kill commands

Then, there are the various kill commands -- including kill, pkill, xkill, and killall. The xkill command is a kill command for X Windows, so I won't cover it here. The others are general purpose and provide very specific or fairly general process termination options.

kill

The kill command expects to be provided with a process ID and offers options such as -9 (often referred to as the “sure kill” option) to control what signal is sent to a running process. With the sure kill option, the kernel stops a process dead in its tracks giving it no time to execute a proper shutdown routine. Because this can result in data loss, this option should only be used when the process cannot otherwise be stopped.

$ kill -9 7911
$ kill -s 9 7911
$ kill -KILL 7911

Other commonly used kill options include:

-1 (-HUP) is the "hang up" option. This option is very safe. Most programs are built to listen for this signal and shut down in an orderly fashion if they do.

-2 (SIGINT) is the same signal that is used when you type Ctrl-C. It is generally safe, though some data loss is possible.

-15 (-TERM) is the "terminate" signal and the default. Like -1 (-HUP), it tells the process to shut down and is generally safe, though -1 (-HUP) is still the gentlest and most predictable.

You can get a complete list of the signals available to you using the kill -l (-l for "list") command.

$ 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

pkill

In its simplest form, the pkill command is handed the name of a process and sends it a SIGTERM (just like the kill command). The benefit is that you do a little less work, not having to look up the process ID, and the command does a little more. Of course, if you're trying to kill a particular process and sixteen of them are running on the system, you'll only be able to shoot down those that belong to you -- unless you're using your superuser powers. Sometimes you want to shut down one particular process. Sometimes you want to kill by name.

If we want to terminate a looping process called "loopy", we can do that easily:

$ pkill loopy

We also could have done it this way, but that would even be more work.

$ ps -ef | grep loopy
shs       4310  4168  0 13:52 pts/0    00:00:00 /bin/bash ./loopy
shs       4314  4168  0 13:52 pts/0    00:00:00 grep --color=auto loopy
$ kill 4310

We also have the option of using the -u (username) option to kill by username, but note that this will attempt to terminate all processes being run by this user.

# pkill -u shs

Alternately, we can kill one specific process for one specific users.

# pkill -u shs loopy

Want to log off real quick and shut down everything you're doing?

$ pkill -u `whoami`

This will kill all processes you might have running, even those running in the background.

The pgrep and pkill commands share a man page since they, after all, are just different sides of the same executable.

Options that work only for pgrep:

  • -d delimiter between process IDs
  • -l (include username in output)

options that work only for pkill

  • -signal (specify signal to be sent)

The number of variety of signals that are available is quite mind-boggling. Under normal circumstances, however, you will probably only make use of these.

Signal Name    Signal Value  Behaviour
SIGHUP          1            Hangup
SIGKILL         9            Kill Signal
SIGTERM        15            Terminate

You can use the numeric or the more descriptive name in your kill commands -- kill -9 and kill -KILL have the same effect.

But as you saw, if you read my post on pgrep, there are numerous other options available with pkill. You can specify the user, the effective userid, the terminal, the signal to be sent, the process group, just the oldest or newest instance of a process, etc.

sample commands

$ pkill -U intruder
$ pkill -U `whoami`
$ pkill -n myproc
$ pkill -f partial
# pkill -9 -P 1984
# pkill -g 123

You can also terminate a specific process by providing more information about the process you're targeting. The -f option allows you to specify more than just the process name using a command pattern like this:

pkill -9 -f "COMMANDNAME -PARAMETERS"

killall

The killall command also provides the kill-by-name capability and, like kill and pkill, sends a SIGTERM by default. If some process seems to be replicating itself with wild abandon, you can shut it down with a command like killall repproc, killall -9 repproc, or killall -q -9 repproc. With the -q options, the command will run "quietly" and you won't see output from the kill operation.

Options available with the killall command include:

-e exact match
-I ignore case
-g process group
-i interactive (ask for confirmation before killing)
-l list known signal names
-o older than
-q work quietly
-r interpret process name as regular expression
-s send the specified signal
-u specified user
-v verbose
-V show version
-w wait for all processes to die
-y younger than
-Z specify security context

Why signals?

Whenever you generate a signal using any form of kill command, the operating system interrupts the target process' normal flow of execution. What happens next depends on the signal being sent.

The pkill and killall commands came about to make terminating process easier by identifying processes by name and other criteria. Going back to our “loopy” example, you could kill the process in one fell swoop, rather than looking up the process ID and then killing it. While the effect may be the same in both cases, the end result depends on whether other processes by the same name are running and whether you have sufficient access to terminate them.

What's easiest depends on what you're trying to do. Is your focus on one particular user, one particular process, or a wider range of users and processes? In general, using additional options allows your kill commands to be more targeted.

Join the Network World communities on Facebook and LinkedIn to comment on topics that are top of mind.
Must read: 10 new UI features coming to Windows 10