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:
Argument handling - all arguments are passed to the first grep
Some flavours of Unix include the grep command in the process list, which is a pain - this script removes it
Exactly one PID is expected - if more than one process is found matching the pattern then the script fails and warns you
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)