315

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.

1
  • did you try echo $!? right after the command, you ran? Mar 6 at 17:32
415

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

my-app &
echo $!
9
  • 1
    It is printing pid as for eg. [1] 893 . I want only number. Sep 4 '14 at 11:47
  • 43
    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
  • 6
    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 Jun 2 '15 at 14:11
  • 17
    @user3153014 String s like "[2] 2625" are printed by shell after starting background task. This is not related to output of echo $! 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. Mar 4 '19 at 17:17
82

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)"
4
  • 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 Jan 22 '16 at 15:12
  • 1
    @EricRenouf post updated! 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
1
  • 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
-5

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.

2
  • 10
    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
  • 4
    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.