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.
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
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.
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
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.
$ 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"
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
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.