Linux Process Termination Made Easy

shell

Finding and killing a process on a Linux system is typically done by sending it a signal using the kill command, specifying the process ID (PID), which we can grab using ps and grep (use ps -ef on some Unix systems):

dmaxwell@kaylee:~$ ps ax | grep gedit 11604 ? Sl 0:01 gedit 11609 pts/5 S+ 0:00 grep gedit dmaxwell@kaylee:~$ kill 11604

But it's sometimes convenient to want to kill a running process by name, or kill a group of running processes with the same name. The most portable way to do this is with the pkill command - this is present on most Linux, Solaris and BSD systems. The simplest way to use pkill is just to specify the process name:

pkill gedit

This sends a TERM signal to any process whose name matches 'gedit', terminating it. If you have a long-running command and can only remember part of the command string, no problem - use -f with pkill:

dmaxwell@kaylee:~$ ps ax | grep name 11902 pts/5 S 5:23 find . -name foo* 11906 pts/5 S+ 0:00 grep name dmaxwell@kaylee:~$ pkill -f name

This would kill the find process (and the grep if it were still running), since part of its full command string contained the substring 'name'. Using pkill in this way will by default gracefully terminate processes, but for stubborn processes that refuse to die, you can specify a different signal. Here we specify a KILL signal, which immediately ends a process.

pkill -KILL name

You can use numeric signals in place of the signal name, for example '-9' is the KILL signal in the last example.

Killing a group of processes is just as easy. Sometimes this is necessary when system shutdown scripts fail, perhaps due to a missing lockfile. Here we kill all the Apache processes running on our server after the shutdown command fails:

root@kaylee:~# /etc/init.d/apache2 stop * Stopping web server apache2 root@kaylee:~# ps ax | grep apache 13124 ? Ss 0:00 /usr/sbin/apache2 -k start 13129 ? S 0:00 /usr/sbin/apache2 -k start 13130 ? S 0:00 /usr/sbin/apache2 -k start 13131 ? S 0:00 /usr/sbin/apache2 -k start 13132 ? S 0:00 /usr/sbin/apache2 -k start 13133 ? S 0:00 /usr/sbin/apache2 -k start 13162 pts/8 S+ 0:00 grep apache root@kaylee:~# pkill apache root@kaylee:~# ps ax | grep apache 13165 pts/8 S+ 0:00 grep apache root@kaylee:~#

Using pkill -f start would also work here, since each of the Apache command lines contains the substring 'start'. The pkill command has many more options, but one other that might be useful is -u, which will allow you to specify a username or ID. In this example we send a TERM signal to all the processes owned by the user 'nobody':

root@kaylee:~# pkill -u nobody

There is a sister command to pkill, pgrep, that takes most of the same options but rather than sending a signal to one or a group of processes, it just displays the process IDs. This can be fed as standard input into other commands. Here is an example: dmaxwell@kaylee:~$ pgrep -d, apache2 14507,14512,14513,14514,14515,14516 dmaxwell@kaylee:~$ ps fvp $(pgrep -d, apache2) PID TTY STAT TIME .. RSS %MEM COMMAND 14507 ? Ss 0:00 .. 11076 0.3 /usr/sbin/apache2 -k start 14512 ? S 0:00 .. 6032 0.2 \_ /usr/sbin/apache2 -k start 14513 ? S 0:00 .. 6028 0.2 \_ /usr/sbin/apache2 -k start 14514 ? S 0:00 .. 6028 0.2 \_ /usr/sbin/apache2 -k start 14515 ? S 0:00 .. 6028 0.2 \_ /usr/sbin/apache2 -k start 14516 ? S 0:00 .. 6028 0.2 \_ /usr/sbin/apache2 -k start

This is particularly useful, since it preserves the header line output by ps, as opposed to something like ps avx | grep apache, which displays the data, but not the column headers. Both pkill and pgrep are documented in the same manual page, so search for either in the FreeBSD or Debian man pages for more info.