How to get process ID of background process?

Viewed 346069

I start a background process from my shell script, and I would like to kill this process when my script finishes.

How to get the PID of this process from my shell script? As far as I can see variable $! contains the PID of the current script, not the background process.

9 Answers

You need to save the PID of the background process at the time you start it:

foo &
FOO_PID=$!
# do other stuff
kill $FOO_PID

You cannot use job control, since that is an interactive feature and tied to a controlling terminal. A script will not necessarily have a terminal attached at all so job control will not necessarily be available.

You can use the jobs -l command to get to a particular jobL

^Z
[1]+  Stopped                 guard

my_mac:workspace r$ jobs -l
[1]+ 46841 Suspended: 18           guard

In this case, 46841 is the PID.

From help jobs:

-l Report the process group ID and working directory of the jobs.

jobs -p is another option which shows just the PIDs.

  • $$ is the current script's pid
  • $! is the pid of the last background process

Here's a sample transcript from a bash session (%1 refers to the ordinal number of background process as seen from jobs):

$ echo $$
3748

$ sleep 100 &
[1] 192

$ echo $!
192

$ kill %1

[1]+  Terminated              sleep 100

I have run into this problem many times provisioning various infrastructure objects. Many times you need a temp proxy using kubectl or a temp port forward. I have found the timeout command to be a good solution for these, since it allows my script to be self contained and I can be assured that the process will end. I try to set small timeouts and rerun the script if I need still need it.

If you're not able to get the PID directly after starting the job, you could also try this and get the PID later:

foo &

# do some stuff and then

pid=$(ps -aux | grep foo | tr -s ' ' | cut -d\  -f2)
kill $pid

Explanation:

  • ps get information for all processes incl. command
  • grep is filtering for your command
  • tr is removing duplicate spaces for cut
  • cut is getting you the column with the PID (2 in this case)
Related