30

I have cobbled together a command to return the process ID of a running daemon:

ps aux | grep daemon_name | awk "{ print \$2 }"

It works perfectly and returns the PID, but it also returns a second PID which is presumably the process I'm running now. Is there a way I can exclude my command from the list of returned PIDs?

I've tested it a few times and it appears my command is always the second PID in the list, but I don't want to grab just the first PID in case it's inaccurate.

tak
  • 303
  • 1
  • 3
  • 4

7 Answers7

30

grep's -v switch reverses the result, excluding it from the queue. So make it like:

ps aux | grep daemon_name | grep -v "grep daemon_name" | awk "{ print \$2 }"

Upd. You can also use -C switch to specify command name like so:

ps -C daemon_name -o pid=

The latter -o determines which columns of the information you want in the listing. pid lists only the process id column. And the equal sign = after pid means there will be no column title for that one, so you get only the clear numbers - PID's.

Hope this helps.

Serg ikS
  • 416
  • 4
  • 7
  • 2
    Using "grep -v grep": Just watch out that you may have a long command line including "grep" (Let's say somebody wrote a grep library=> "-Llibgrep.so" or "-cp libgrep.jar". At least I would repeat the pattern : grep -v "grep daemon_name" – phil_w Apr 09 '15 at 15:01
25

You can use a character class trick. "[d]" does not match "[d]" only "d".

 ps aux | grep [d]aemon_name | awk "{ print \$2 }"

I prefer this to using | grep -v grep.

RedGrittyBrick
  • 81,981
  • 20
  • 135
  • 205
  • Heh that's a clever trick, I like it. I'm keeping things simple at the moment though while I'm learning, and `| grep -v grep` will be easier to understand when I revisit my code. – tak Apr 07 '12 at 12:29
  • I am trying to understand how this [h]ack works. Could you please explain what you mean with `"[d]" does not match "[d]" only "d"`? – Nowaker Sep 28 '13 at 21:13
  • 2
    @Damian: The square brackets are *metacharacters* (delimiting a set of characters) in the search expression so the `grep` command won't match the `ps` output line for the `grep` command itself (what tak called "a second PID" in the original question). expression `a[xy]d` does **not** match text `a[xy]d` but it does match text `axd` or text `ayd`. Hence expression `[f]oo` matches text `foo` but not text `[f]oo`. I hope that is clear. – RedGrittyBrick Sep 28 '13 at 21:34
  • Okay, I was wrong about ARGV. This is just a regexp. Thanks. – Nowaker Sep 29 '13 at 01:29
  • Devilishly clever! Had to think about it for a moment -- thanks! – Subfuzion Oct 23 '13 at 18:46
  • I'm also using the `-w`, matching only whole words, and not killing all `bash` with the `ps -axu | grep [b]a` :) The `ps...|grep -w [b]a` is safer. – clt60 Sep 09 '14 at 08:35
  • Correct me if I am wrong, but this also should work on any position of the grepped character: ps aux| grep "daem[o]n_name" – meso_2600 Mar 23 '16 at 09:54
  • @RedGrittyBrick It does not work for example: `ps aux | grep [s]cript1` or `ps aux | grep [s]cript2`. The grep line is still shown. Could you help to comment about the solution ? Many thanks ! O_O – SOUser Nov 13 '17 at 14:07
  • @RedGrittyBrick My fault. It seems the line is shown because of the previous searches. – SOUser Nov 13 '17 at 14:09
  • On MacOS I had to use quotes, i.e. `ps | grep "[v]i"` Example, `ps | grep "vi"` gave the following two lines: `will % ps | grep vi 29698 ttys000 0:00.06 vi src/strings/main.cpp 29736 ttys002 0:00.00 grep vi` whereas `ps | grep "[v]i"` gave just one line: `will % ps | grep "[v]i" 29698 ttys000 0:00.06 vi src/strings/main.cpp` – Will Jul 28 '23 at 13:23
16

Avoid parsing ps's output if there are more reliable alternatives.

pgrep daemon_name
pidof daemon_name
u1686_grawity
  • 426,297
  • 64
  • 894
  • 966
3

The ps -C option is not universal on all Unix based systems but if it works on your systems. Instead I would avoid grep altogether:

ps aux | awk '/daemon_name/ && !/awk/ { print $2 }'

No need to escape anything in single quotation marks. ps aux will give you the full list of processes on most Unix based systems and awk is typically installed by default.

MOG73
  • 46
  • 2
3

Use pgrep to look for the pid of a process by name:

pgrep proc_name

With extra process name in the result (-l):

pgrep -l proc_name

Look for and display the process name (-l) and arguments (-f):

pgrep -lf proc_name_or_argument

The good thing about pgrep is that it will never report itself as a match. But you don't need to get the pid by pgrep and then kill the corresponding process by kill. Use pkill instead:

pkill proc_name

Specify the SIGKILL signal (-9 or -KILL) instead of SIGTERM (by default):

pkill -9 proc_name

Look for the process name (-l) and arguments (-f), ask for confirmation (-I) before killing it by SIGKILL signal (-9 or -KILL):

pkill -KILL -Ilf proc_name_or_argument

Notice that the -I option is only available on some versions of pkill, e.g. the one on the OS X Mavericks.

Rockallite
  • 321
  • 2
  • 4
0

If you are using bash, you can also do this in the following manner by making use of ps -eaf

PIDS=$(ps -eaf)
PID=$(echo "$PIDS" | grep "process_name" | awk '{print $2}')
echo $PID
0

this line gives you back the pid (process id) excluding "grep"

PID=$(ps aux | grep '/usr/bin/python2.7 manage.py SES__boto3_sqs_read' | grep -v grep)