I want to start process (eg. myCommand) and get its pid (to allow to kill it later).

I tried ps and filter by name, but I can not distinguish process by names

myCommand
ps ux | awk '/<myCommand>/ {print $2}' 

Because processes names are not unique.

I can run process by:

myCommand &

I found that I can get this PID by:

echo $!

Is there any simpler solution?

I would be happy to execute myCommand and get its PID as a result of one line command.

link|improve this question
feedback

6 Answers

up vote 7 down vote accepted

What can be simpler than echo $!? As one line:

myCommand & echo $!
link|improve this answer
Thank you merging these commands with "&" helped me a lot. – rafalmag Nov 27 '10 at 12:09
feedback

I do not know of any simpler solution, but isn't using $! good enough? You can always assign the value to some other variable if you need it later, as said by others.

As a side note, instead of piping from ps you could use pgrep or pidof.

link|improve this answer
feedback

Wrap the command in a small script

#!/bin/bash
yourcommand &
echo $! >/path/to/pid.file
link|improve this answer
feedback

You can use something like:

$ myCommand ; pid=$!

Or

$ myCommand && pid=$!

The two commands can be joints using ; or &&. In the second case, the pid will be set only if the first command succeeds. You can get the process id from $pid.

link|improve this answer
1  
OP wants to get the PID so he can kill it later. ; and && require the original process to exit before the echo $! is executed. – Iain Nov 24 '10 at 8:58
Yes, you are right. This will give you the pid after myCommand has terminated. – Khaled Nov 24 '10 at 9:02
1  
Referencing $! after && or ; will never give you the PID of the process started for the left-hand side of the command separator. $! is only set for processes launched asynchronously (e.g. usually with & but some shells also have other methods). – Chris Johnsen Nov 24 '10 at 9:47
feedback

use exec from a bash script after registering the pid to a file:

example:

suppose you have a script named "forever.sh" that you want to run with args p1,p2,p3

forever.sh sourcecode:

#!/bin/sh

while [ 1 -lt 2 ] ; do
    logger "$0 running with parameters \"$@\""
    sleep 5
done

create a reaper.sh:

#!/bin/sh

echo $$ > /var/run/$1.pid
exec "$@"

run forever.sh through reaper.sh:

./reaper.sh ./forever.sh p1 p2 p3 p4 &

forever.sh does nothing more than logging a line to syslog each 5 seconds

you now have the pid in /var/run/forever.sh.pid

cat /var/run/forever.sh.pid 
5780

and forever.sh is running aok. syslog grep:

Nov 24 16:07:17 pinkpony cia: ./forever.sh running with parameters "p1 p2 p3 p4"

you can see it in the process table:

ps axuwww|grep 'forever.sh p1' |grep -v grep
root      5780  0.0  0.0   4148   624 pts/7    S    16:07   0:00 /bin/sh ./forever.sh p1 p2 p3 p4
link|improve this answer
oh, and the "oneliner": /bin/sh -c 'echo $$>/tmp/my.pid && exec program args' & – malfaux Nov 24 '10 at 14:28
1  
To properly preserve internal whitespace in the arguments, you should use exec "$@" instead of exec $*. Technically what you need to preserve is not whitespace but occurrences of the characters in the IFS shell parameter (which defaults to space, tab, and newline). – Chris Johnsen Nov 25 '10 at 3:53
point taken. :) – malfaux Nov 25 '10 at 7:54
Thank you, I did not know $$ parameter. It can be very useful. – rafalmag Nov 27 '10 at 12:12
feedback

You have it right, but you might also be interested in reading this:

Process Management

link|improve this answer
feedback

Your Answer

 
or
required, but never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.