Share

Finding the process ID (PID) of a command in unix

Getting the PID of a running command is something I do daily, particularly by grepping on the name, e.g.:

$ ps auxww | grep ruby
root      3035  0.0  0.3  77672 13392 ?        Sl   Mar18   0:03 ruby /home/jon/.rvm/rubies/ruby-1.9.3-p286/bin/gem server --daemon --port=8808
jon       6943  0.0  0.0  13592   916 pts/6    S+   09:26   0:00 grep ruby
root     10152  0.0  0.0  78924  3476 ?        Sl   Mar18   0:00 ruby /home/jon/.rvm/gems/ruby-1.9.3-p286/bin/chain-reactor start /home/jon/Chainfile.rb
root     26563  0.0  0.3 201084 14852 ?        Sl   Mar18   0:50 /home/jon/.rvm/gems/ruby-1.9.3-p286/bin/breaktime

The second column gives the process ID, which I then pick out to do something with (e.g. send a signal). You can use awk to print just that column, like so:

$ ps auxww | grep ruby | awk '{print $2}'
3035
6943
10152
26563

However, typing out this command each time is a bit of a pain, so I created a bash script to give me the process ID given a grep string:

#!/bin/bash
me='findpid'
if [ $# -lt 1 ]
then
    echo "$me: some arguments are required, a grep expression for filtering processes" >&2
    exit
fi

output=$(ps auxww | grep "$*" | grep -v grep | grep -v $0)
lines=`echo "$output" | wc -l`

if [ $lines -gt 1 ]
then
    echo "$me:  there are too many pids matching the expression: \\"$*\\"" >&2
    echo
    echo "$output" >&2
    exit 2
elif [ -z "$output" ]
then
    echo "$me:  there are no processes matching the expression: \\"$*\\"" >&2
    exit 1
fi

echo "$output" | awk '{print $2}'

There are several things that this script gives you:

  1. Argument handling - all arguments are passed to the first grep

  2. Some flavours of Unix include the grep command in the process list, which is a pain - this script removes it

  3. Exactly one PID is expected - if more than one process is found matching the pattern then the script fails and warns you

  4. It also fails if no processes are found matching the pattern

I added this script to /usr/local/bin/findpid and made it executable. You can then use it like this:

$ findpid breaktime
26563

Or to see the case where it fails:

$ findpid ruby
findpid:  there are too many pids matching the expression: "ruby"

root      3035  0.0  0.3  77672 13388 ?        Sl   Mar18   0:03 ruby /home/jon/.rvm/rubies/ruby-1.9.3-p286/bin/gem server --daemon --port=8808
root     10152  0.0  0.0  78924  3472 ?        Sl   Mar18   0:00 ruby /home/jon/.rvm/gems/ruby-1.9.3-p286/bin/chain-reactor start /home/jon/Chainfile.rb
root     26563  0.0  0.3 201084 14852 ?        Sl   Mar18   0:50 /home/jon/.rvm/gems/ruby-1.9.3-p286/bin/breaktime

You can also embed this in other commands, such as kill:

$ kill $(findpid breaktime)
← Previous post: Ruby rocks: averaging an array of numbers to return a set number Next post: Wait for a unix process to finish →
comments powered by Disqus