Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get PID from within backgrounded function in shell script

Tags:

bash

shell

ksh

This looks like a duplicate of Get pid of function executed in background but it isn't. The accepted answer in that was the scripts parent process id.

The following script:

#!/bin/bash

function foo {
  # I want to know my PID
  echo foo PID=$$
  echo foo PPID=$PPID
  sleep 1
}

echo Script PID=$$
echo Script PPID=$PPID
foo &
echo job PID=$!
ps -fH
wait

Produces the following output:

Script PID=3694
Script PPID=27899
job PID=3695
foo PID=3694
foo PPID=27899
UID        PID  PPID  C STIME TTY          TIME CMD
fred     27899  6622  0 11:03 pts/10   00:00:00 /bin/bash
fred      3694 27899  0 15:10 pts/10   00:00:00   /bin/bash /tmp/test
fred      3695  3694  0 15:10 pts/10   00:00:00     /bin/bash /tmp/test
fred      3697  3695  0 15:10 pts/10   00:00:00       sleep 1
fred      3696  3694 99 15:10 pts/10   00:00:00     ps -fH

Since foo() is run in the background I expected $$, within foo, to evaluate to its PID (3695) but it doesn't it evaluates to the calling scripts PID (3694).

Within the function foo, how do I get its own PID?

UPDATE: Changed ps -fp $! to ps -fH as requested

like image 682
Paranoid Avatar asked Mar 14 '26 10:03

Paranoid


2 Answers

When backgrounding a function, Bash likely uses a subshell. The PID and PPID variables are not changed, but if you echo the BASHPID variable, you will see it change inside your function.

I think the behavior you see is intended, but functions simply act differently compared to eternal programs launched by the shell.

You can force a separate process to be launched by putting the code from your function in a separate script and call it with

bash `other_script`

That should create a new process no matter what shell you use.

You will need to export any variable needed in the child, and will not be able to make assignments to variables in the child that would be visible to the parent.

like image 125
Fred Avatar answered Mar 15 '26 22:03

Fred


I've found a simple way to do it that works for both bash and ksh (and possibly other shells).

$SHELL -c 'echo $PPID'

When the above command is invoked PPID is set to the calling process which happens to be the function foo.

like image 22
Paranoid Avatar answered Mar 16 '26 00:03

Paranoid



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!