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.
The output is correct.
Here's from the man page of bash.
To get the PID inside of a subshell, you may use BASHPID. This is a bash only env variable.
Your new script will look like this.
@John1024 's answer is great, but there's a little problem in there.
when a command run like (...), the command will run in a new subprocess, so
will return process_id of (...), not the function's process id that call (...)
if you want the function's process_id, you can just run:
and the process_id will be outputed to stderr
if you want get the function's process_id form a variable, you can run:
then you can get the pid from variable ${func_pid}
note: don't run this command in (...), otherwise it'll return the process_id of (...)
Environment:
SUSE Linux Enterprise Server 10 SP2 (i586)
GNU bash, version 3.1.17(1)-release (i586-suse-linux) Copyright (C) 2005 Free Software Foundation, Inc.
Result:
If you use Linux-kernel, you can use Linux-kernel's
/proc/self
feature to do this:In simplest form:
cd -P /proc/self && basename "${PWD}"
To keep the
PWD
andOLDPWD
variable:PWD_BACKUP="${PWD}";OLDPWD_BACKUP="${OLDPWD}";cd -P /proc/self && basename "${PWD}";cd "${PWD_BACKUP}";OLDPWD="${OLDPWD_BACKUP}"
For example:
Modern bash
If you are running bash v4 or better, the PID of the subshell is available in
$BASHPID
. For example: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:
(Hat tip: kubanczyk)
Why the colon?
Notice that, without the colon, the work-around does not work:
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
). ThePPID
approach works fordash
but with yet another twist: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
, andzsh
but notksh
: