11

$$ gives process id of the script process when used in a script, like this:

Example 1

#!/bin/bash
# processid.sh
# print process ids

ps -o cmd,pid,ppid
echo "The value of \$\$ is $$"

$ ./processid.sh 
CMD                           PID  PPID
bash                        15073  4657
/bin/bash ./processid.sh    15326 15073
ps -o cmd,pid,ppid          15327 15326
The value of $$ is 15326

Observe the pid given by $$ and ps is 15326

My shell prompt is pid 15073

But in a subshell, $$ gives pid of parent shell (which is 15073)

Example 2

$ ( ps -o cmd,pid,ppid ; echo $$ )
CMD                           PID  PPID
bash                        15073  4657
bash                        15340 15073
ps -o cmd,pid,ppid          15341 15340
15073

Here subshell is pid 15340

Question: Why so? Isn't the script also running in a subshell? What's the difference between the subshell in example 2 and the shell in which the script runs in example 1?

codeforester
  • 39,467
  • 16
  • 112
  • 140
Ankur Agarwal
  • 23,692
  • 41
  • 137
  • 208

4 Answers4

14

I tried and escaping (to pass the $$ to the subshell) does not work as the subshell inherits the $$ value from the parent bash. The solution to this is to use $BASHPID.

(echo $$; echo $BASHPID)

prints the PID from the parent shell and from the subshell.

flolo
  • 15,148
  • 4
  • 32
  • 57
9

From the bash manpage:

   $      Expands  to  the  process ID of the shell.  In a () subshell, it
          expands to the process ID of the current  shell,  not  the  sub-
          shell.
Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
6

The replacement takes place in the parent shell; the subshell hasn't been started by the time the substitution takes place.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • Can you please be little more descriptive please ? I am not able to follow what you are saying. Thanks! – Ankur Agarwal Apr 11 '11 at 04:33
  • @abc: Because your subshells never sees the $$. It got invoked with `( echo 1234 )` as your parent shell already substitutes the $$ with its PID. you have to escape it, so the subshell can see the $$. – flolo Apr 11 '11 at 06:45
  • @flolo How do I escape it. Can you please give the code ? I tried \$$, $\$. That did not do anything. – Ankur Agarwal Apr 11 '11 at 22:31
  • I don't think you can escape it. You can use `$BASHPID` as mentioned above, or the more portable `sh -c 'echo $PPID'`. – Idelic Apr 12 '11 at 09:09
  • 6
    Yeah, this isn't about who does the replacement; $$ *is* evaluated in the subshell, it just intentionally evaluates to the PID of the main shell as the manpage says. – Torne May 29 '12 at 15:01
1

A more portable way, linux-only, but also compatible with dash:

read -r my_pid _ < /proc/self/stat
echo $my_pid
drizzt
  • 737
  • 1
  • 7
  • 14
  • It was worring me because `$BASHPID` is only for bash! `sh -c 'echo $$;echo $$&&sleep 5&sleep 1;echo $!'` I want the second number be equals to the third, and `$BASHPID` is blank, so: `sh -c 'echo $$;read a _ – Tiago Pimenta Jan 08 '15 at 17:29