How can I get the pid of a subshell?

$ echo $BASHPID
37152
$ ( echo $BASHPID )
18633

From the manual:

BASHPID

Expands to the process ID of the current bash process. This differs from $$ under certain circumstances, such as subshells that do not require bash to be re-initialized.

$

Expands to the process ID of the shell. In a () subshell, it expands to the process ID of the current shell, not the subshell.

Related:

  • Do parentheses really put the command in a subshell?, especially parts of Gilles' answer.

In addition to bash's $BASHPID, you can do it portably with:

pid=$(exec sh -c 'echo "$PPID"')

Example:

(pid=$(exec sh -c 'echo "$PPID"'); echo "$$ $pid")

You can make it into a function:

# usage getpid [varname]
getpid(){
    pid=$(exec sh -c 'echo "$PPID"')
    test "$1" && eval "$1=\$pid"
}

Notice that some shells (eg. zsh or ksh93) do NOT start a subprocess for each subshell created with (...); in that case, $pid may be end up being the same as $$, which is just right, because that's the PID of the process getpid was called from.