Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get pid of current subshell

Tags:

bash

sh

I am trying to get the pid of a currently executing subshell - but $$ is only returning the parent pid:

#!/usr/bin/sh  x() {   echo "I am a subshell x echo 1 and my pid is $$" }  y() {   echo "I am a subshell y echo 1 and my pid is $$" }   echo "I am the parent shell and my pid is $$" x & echo "Just launched x and the pid is $! "  y & echo "Just launched y and the pid is $! "  wait 

Output

I am the parent shell and my pid is 3107 Just launched x and the pid is 3108 I am a subshell x echo 1 and my pid is 3107 Just launched y and the pid is 3109 I am a subshell y echo 1 and my pid is 3107 

As you can see above, when I run $$ from the function that I've backgrounded, it does not display the PID as when I do $! from the parent shell.

like image 805
awojo Avatar asked Dec 22 '13 03:12

awojo


People also ask

Which variable gives the PID of the current shell?

There is a special variable called "$" and "$BASHPID" which stores the process ID of the current shell. Go ahead and run the below command to see what is the process ID of your current shell.

How do I find the process ID of a running script in Unix?

A process is nothing but running instance of a program and each process has a unique PID on a Unix-like system. The easiest way to find out if process is running is run ps aux command and grep process name. If you got output along with process name/pid, your process is running.


1 Answers

Modern bash

If you are running bash v4 or better, the PID of the subshell is available in $BASHPID. For example:

$ echo $$ $BASHPID ; ( echo $$ $BASHPID  ) 32326 32326 32326 1519 

In the main shell, $BASHPID is the same as $$. In the subshell, it is updated to the subshell's PID.

Old bash (Version 3.x or Earlier)

Pre version 4, you need a workaround:

$ echo $$; ( : ; bash -c 'echo $PPID' ) 11364 30279 

(Hat tip: kubanczyk)

Why the colon?

Notice that, without the colon, the work-around does not work:

$ echo $$; ( bash -c 'echo $PPID' ) 11364 11364 

It appears that, in the above, a subshell is never created and hence the second statement returns the main shell's PID. By contrast, if we put two statements inside the parens, the subshell is created and the output is as we expect. This is true even if the other statement is a mere colon, :. In shell, the : is a no-operation: it does nothing. It does, in our case however, force the creation of the subshell which is enough to accomplish what we want.

Dash

On debian-like systems, dash is the default shell (/bin/sh). The PPID approach works for dash but with yet another twist:

$ echo $$; (  dash -c 'echo $PPID' )  5791 5791 $ echo $$; ( : ; dash -c 'echo $PPID' ) 5791 5791 $ echo $$; (  dash -c 'echo $PPID'; : )    5791 20961 

With dash, placing the : command before the command is not sufficient but placing it after is.

POSIX

PPID is included in the POSIX specification.

Portability

mklement0 reports that the following works as is with bash, dash, and zsh but not ksh:

echo $$; (sh -c 'echo $PPID' && :) 
like image 66
John1024 Avatar answered Oct 07 '22 21:10

John1024