djangoproject.com | nginx.org | python.org | linux.com
version seven.
  http://demongin.org
demongin.org - Stupid Linux Tricks: the Basics of pkill and pgrep

Stupid Linux Tricks: the Basics of pkill and pgrep

A tiny tutorial on basic, sysadmin-style use of pgrep and pkill


Sunday, 2010-03-28 | AlmostEffortless, Careerism, Programming

When I say, "If you don't know the basics of pgrep and pkill, you really need to make it a priority to learn them", what I really mean is, "I just recently learned how to use pgrep and pkill myself and I'm really, really excited about them."

Whether you're automating processes on the server across the Internet or you're trying to wrangle the processes on the client right in front of you, there really is no classier or more efficient way to do it than with these two programs. What follows are two examples of how, using nothing more than some elementary bash, you can quickly retrieve PID numbers, paths to processes and basically micromanage your system into submission.

The first thing to get down with is the l flag. It'll give you the PID as well as the process name. This is useful if you've got processes that are related, but that don't have exactly the same name:

toconnell@kumiko:~$ pgrep -l thunderbird
7425 thunderbird
7433 thunderbird-bin
The f flag is kind of like the industrial strength version of this. When you throw down the f and the l together, you get a PID and an absolute path:
toconnell@kumiko:~$ pgrep -lf thunderbird
7425 /bin/sh /home/toconnell/thunderbird/thunderbird
7428 /bin/sh /home/toconnell/thunderbird/run-mozilla.sh /home/toconnell/thunderbird/thunderbird-bin
7433 /home/toconnell/thunderbird/thunderbird-bin
If you've been paying attention, you'll notice that I got three results from my second command. This is because the f greps against the full path of all running processes. This can be a real life saver when you've got (as above) processes spawning other processes or when you've got to start one process to start another. I frequently find myself doing this with .jar files.

For example, I use tn5250j (an old-timey IBM "green screen" emulator) at work. Nothing against their project, but when I end my tn5250j sessions, I've found that some of the processes that it starts tend not to die completely. I've also found that If I want to look for stranded or undead processes with a simple pgrep, I get nothing. This is because when I start the emulator, my KDE shortcut uses the following syntax:

$ /home/toconnell/jre1.6.0/bin/java -jar /home/toconnell/tn5250j/tn5250j.jar
If I pgrep for java, of course, renegade tn5250j processes will turn up. But so will all my other active java processes:
toconnell@kumiko:~$ pgrep -l java
26100 java
26131 java
If, however, I use the f, and grep against the full path, I see that these are not both tn5250j processes:
toconnell@kumiko:~$ pgrep -lf java
26100 /home/toconnell/jre1.6.0/bin/java -jar /home/toconnell/tn5250j/tn5250j.jar
26131 /usr/bin/java -jar /usr/bin/tightvnc/classes/VncViewer.jar HOST victoria PORT 5900
If I use the f and use "tn5250" as my grep term, I only get the process I want.

Which is really handy if I've got a bunch of these things running around and I want them all dead. pkill will take an f flag and neatly dispose of all of my errant java processes. As a sort of "set it and forget it" method of keeping these things from stacking up, I've created a job in /etc/cron.daily/ that kills all of the stranded processes from yesterday before I even sit down at my desk:

#!/bin/bash
set -e
`which pkill` -f tn5250 > /dev/null 2&>1
exit

But this is only the beginning of the fun. pgrep and pkill are even more invaluable in an emergency, e.g. when you've got a bunch of users (probably system users (e.g. daemons), but maybe human ones too) running around and you only want to kill the processes that one of your users has started.

Let's say that I've got two separate instances of postgres running, one belongs to the user postgres81, the other belongs to postgres83, and the new one happens to be running amok. You're desperate enough to restore order that you're ready to break Rule Number One and kill the postmaster.

The fastest way to put a bullet in your malfunctioning database processes without bothering any of your stable processes?

# pkill -f -u postgres83