Why is $$ returning the same id as the parent process?
314,167
Solution 1
$$
is defined to return the process ID of the parent in a subshell; from the man page under "Special Parameters":
$ Expands to the process ID of the shell. In a () subshell, it expands to the process ID of the current shell, not the subshell.
In bash
4, you can get the process ID of the child with BASHPID
.
~ $ echo $$
17601
~ $ ( echo $$; echo $BASHPID )
17601
17634
Solution 2
You can use one of the following.
-
$!
is the PID of the last backgrounded process. -
kill -0 $PID
checks whether it's still running. -
$$
is the PID of the current shell.
Solution 3
- Parentheses invoke a subshell in Bash. Since it's only a subshell it might have the same PID - depends on implementation.
- The C program you invoke is a separate process, which has its own unique PID - doesn't matter if it's in a subshell or not.
-
$$
is an alias in Bash to the current script PID. See differences between$$
and$BASHPID
here, and right above that the additional variable$BASH_SUBSHELL
which contains the nesting level.
Solution 4
Try getppid()
if you want your C program to print your shell's PID.
Solution 5
this one univesal way to get correct pid
pid=$(cut -d' ' -f4 < /proc/self/stat)
same nice worked for sub
SUB(){
pid=$(cut -d' ' -f4 < /proc/self/stat)
echo "$$ != $pid"
}
echo "pid = $$"
(SUB)
check output
pid = 8099
8099 != 8100
Related videos on Youtube
Comments
-
ruanhao almost 2 years
I have problem with Bash, and I don't know why.
Under shell, I enter:echo $$ ## print 2433 (echo $$) ## also print 2433 (./getpid) ## print 2602
Where
getpid
is a C program to get current pid, like:int main() { printf("%d", (int)getpid()); return 0; }
What confuses me is that:
- I think "(command)" is a sub-process (am i right?), and i think its pid should be different with its parent pid, but they are the same, why...
- When I use my program to show pid between parenthesis, the pid it shows is different, is it right?
- Is
$$
something like macro?
Can you help me?
-
chepner over 10 yearsNote that
getpid
would show a different process ID even if it weren't run in a subshell. -
Ben over 4 years@Marian
echo $$ $BASHPID ; ( echo $$ $BASHPID )
demonstrates that it does. Round brackets create a subshell. The statements may change variable values, and the parent shell must not see those changes. This is implemented as afork()
operation.
-
Martin Bouladour almost 7 years"parent" is a bit misleading (at least it was to me), it's actually the "top level" shell. For instance :
echo $$; (echo $$; (echo $$))
echoes the same pid three times -
chepner almost 7 yearsRight; I should have said that the value is inherited from a parent shell (which inherited its value from its parent, etc). The top level shell sets it initially, rather than inheriting from its (non-shell) parent process.
-
Alexander Mills almost 5 years
$ Expands to the process ID of the shell
does it tho?echo $
just echoes the literal $. -
chepner almost 5 years@AlexanderMills Well, yes;
$
alone is not a parameter expansion. The man page is referring to the name of the special parameter, which is$
; it's not claiming that$
alone expands. -
Alexander Mills almost 5 yearsOk I honestly have no idea what that means, but
echo $BASHPID
works in bash 4 and 5 (but not version 3.2.57 on MacOS) -
chepner almost 5 yearsAll parameter expansions start with
$
, but$
is also the name of one of the special parameters.$
,#
,@
,*
, etc are some of the special parameters;$$
,$#
,$@
,$*
, etc are the expressions that expand to the value of each. -
Martin Dorey over 4 yearsNice idea, but won't that get you the pid of the fork the shell has run to capture the output of cut? If I run it twice, once with echo $(...) and once without, then I get different answers.
-
Isaac Freeman over 4 yearsShouldn't the second bullet be
kill -0 $!
if we're talking about background processes?PID
isn't set to anything by default. -
joseluisq over 3 yearsOr if you use Rust just try
nix::unistd::getppid()
which will get the pid of current processes' parent - docs.rs/nix/0.18.0/nix/unistd/fn.getppid.html