240

I want to have a shell script like this:

my-app &
echo $my-app-pid

But I do not know how the get the pid of the just executed command.

I know I can just use the jobs -p my-app command to grep the pid. But if I want to execute the shell multiple times, this method will not work. Because the jobspec is ambiguous.

325

The PID of the last executed command is in the $! shell variable:

my-app &
echo $!
  • 1
    It is printing pid as for eg. [1] 893 . I want only number. – user3153014 Sep 4 '14 at 11:47
  • 33
    It should be noted that this stands for programs started in the background. If no background processes have been started the parameter is not set. – ramrunner Nov 17 '14 at 21:52
  • 5
    Another worthy solution is suggested in (a comment to an answer to) How to get pid of just started process: oh, and the "oneliner": /bin/sh -c 'echo $$>/tmp/my.pid && exec program args' & – sysfault Nov 24 '10 at 14:28 – imz -- Ivan Zakharyaschev Jun 2 '15 at 14:11
  • 14
    @user3153014 String s like "[2] 2625" are printed by shell after starting background task. This is not related to output of echo $! – Petr Gladkikh Jul 26 '15 at 5:21
  • I usually use such code in a script when I need to wait until the process ends. my-app & myVar=$! ; fg. fg brings the process to foreground again. I can then print echo $myVar later and I'm pretty sure that the my-app has already finished. – Vrata Blazek Mar 4 at 17:17
63

Get PID:

#!/bin/bash
my-app &
echo $!

Save PID in variable:

#!/bin/bash
my-app &
export APP_PID=$!

Save all instances PID in text file:

#!/bin/bash
my-app &
echo $! >>/tmp/my-app.pid

Save output, errors and PID in separated files:

#!/bin/bash
my-app >/tmp/my-app.log 2>/tmp/my-app.error.log &
echo $! >>/tmp/my-app.pid

echo "my-app PID's: $(cat /tmp/my-app.pid)"
  • 3
    The question didn't ask about redirection, then your answer is the mostly the same as the accepted one except that if an instance of my-app finishes, and perhaps even worse its PID gets reused later, you'll have bad information in your file. I don't think this answer adds much of value to the existing accepted answer really – Eric Renouf Jan 22 '16 at 15:12
  • @EricRenouf post updated! – Eduardo Cuomo Jan 22 '16 at 15:42
  • another derivative that might be useful. This gets the PID and at the same time treats it as a (mostly) foreground process: sleep 4 | grep INVALID & export MY_PID=$!; fg; echo $MY_PID returned with $? ` – mlathe Apr 26 '18 at 21:53
  • isnt APP=main & a way to grab PID? – MrMesees Aug 30 '18 at 7:54
3

Try something like

pidof my_app >> /tmp/my_app.pid
  • external command, and slow, if system can give PID directly why searching through all processes to find just that? and also, can't be certain you'll get correct value – papo Jan 2 at 8:13
0

You could also use pkill for this With pkill you can just specify the process name and avoid getting the pid

https://linux.die.net/man/1/pkill

-4

Try something like this:

 ps ef | grep "[m]y-app" | awk '{print $2}'

Placing the first letter of your process between [ ] makes sure you do not get the grep process in your list. If needed you can also add a grep on your username.

  • 9
    That's very fragile at best and doesn't work if my-app is executed more than once - davidshen84 specifically worries about that cas. – Mat Jan 30 '12 at 12:10
  • 2
    If you even go this route, you should use pgrep instead. – Willem Jan 19 '15 at 12:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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