267

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.

354

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
  • 36
    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 '19 at 17:17
68

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
  • 2
    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 '19 at 8:13
-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

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