343

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? Commented Mar 6, 2021 at 17:32

4 Answers 4

451

The PID of the most recently executed background (asynchronous) command is in the $! shell variable:

my-app &
echo $!
9
  • 1
    It is printing pid as for eg. [1] 893 . I want only number. Commented Sep 4, 2014 at 11:47
  • 51
    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
    Commented Nov 17, 2014 at 21:52
  • 7
    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 Commented Jun 2, 2015 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 $! Commented Jul 26, 2015 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. Commented Mar 4, 2019 at 17:17
89

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 Commented Jan 22, 2016 at 15:12
  • 1
    @EricRenouf post updated! Commented Jan 22, 2016 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
    Commented Apr 26, 2018 at 21:53
  • isnt APP=main & a way to grab PID?
    – MrMesees
    Commented Aug 30, 2018 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
    Commented Jan 2, 2019 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
  • 11
    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
    Commented Jan 30, 2012 at 12:10
  • 4
    If you even go this route, you should use pgrep instead.
    – Willem
    Commented Jan 19, 2015 at 12:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .