subshell pid

How to get the pid of the current process from within a subshell

One of the awesome things about shell scripting (maybe the only awesome thing actually) is that you can easily create subshells that can see the variables from the parent process:

foo="my variable"
{ echo "foo=$foo" } # command grouping - runs in same process - prints 'foo=my variable'
( echo "foo=$foo" ) # subshell - runs in a new process - prints 'foo=my variable'

I find it somewhat surprising, but $$ always evaluates to the pid of the top-level instance, even when used inside a subshell. Probably this behavior dates back decades and now it must be maintained for historical reasons. It's kind of convenient sometimes - you can use it to generate temporary files and share them between subshells easily - but I wish there was an easy way to get the PID of a subshell.

Bash 4 introduced the variable $BASHPID which works - but only if you're using bash, and it has to be a recent version. MacOS ships with an ancient version of Bash that doesn't support $BASHPID.

What can you do instead? This is the best way that I've found is:

my_pid=$(sh -c 'echo $PPID')

It works by forking/execing a new instance of sh, then evaluating the string echo $PPID, which is the pid of the parent process. i.e. We create a child process that prints its parent pid.

Note: $PPID has the same behavior as $$ in subshells - it always refers to the parent of the top-level instance. But we avoid that behavior by passing the string echo $PPID to sh, so it doesn't get expanded by the current shell.


If you enjoyed this post, please let me know on Twitter or Bluesky.

Posted October 30, 2025.

Tags: #shell, #mac