I made a check of it as well and no, I don't think it (-c
) summons a subshell. If we refer to sh
itself, the yes sh
is a shell that gets summoned, but not if it's about a subshell within sh
itself. We can verify this by running a command like:
# bash -c 'pstree -p; echo Value of PPID in Callee: $PPID; echo Callee PID: $BASHPID / $$'; echo "Caller PID: $$"
bash(28860)───bash(17091)───pstree(17092)
Value of PPID in Callee: 28860
Callee PID: 17091 / 17091
Caller PID: 28860
As you can see the called shell (17091) and the caller shell (28860) are both connected directly as child-parent. There's nothing in between them. $BASHPID
and $$
are even the same, in which case should be different if you're on a subshell. This just tells that there's no subshell summoned when calling commands with -c
.
There's only one special behavior to this, and that is when summoning a single external binary e.g.:
# bash -c 'pstree -p'; echo "Caller PID: $$"
bash(28860)───pstree(17124)
Caller PID: 28860
There bash saves itself from forking and decided to just directly exec() the only command. You might think that perhaps bash always does that to the last command if the command refers to an external executable binary, but no it doesn't:
# bash -c 'echo Value of PPID in Callee: $PPID; echo Callee PID: $BASHPID / $$; pstree -p'; echo "Caller PID: $$"
Value of PPID in Callee: 28860
Callee PID: 17128 / 17128
bash(28860)───bash(17128)───pstree(17129)
Caller PID: 28860
Now about
echo $BASHPID, $BASH_SUBSHELL
and
sh -c "echo $BASHPID, $BASH_SUBSHELL"
and the results are the same.
It should be the same if echo $BASHPID, $BASH_SUBSHELL
is executed in the same shell since "echo $BASHPID, $BASH_SUBSHELL"
is first expanded by the shell that interprets the command before it's passed as an argument to sh
. If BASHPID
is let's say 28860
and BASH_SUBSHELL
0, then the expanded value of "echo $BASHPID, $BASH_SUBSHELL"
is 'echo 28860, 0'
in which case the command would actually be sh -c 'echo 28860, 0'
. The proper way to this actually is to use a single quote to allow interpretation only within the context of the new called shell: sh -c 'echo $BASHPID, $BASH_SUBSHELL'
, although I'm not really sure if the command itself would be helpful for testing.
So basically what I'm saying is that the test echo $BASHPID, $BASH_SUBSHELL
+ sh -c "echo $BASHPID, $BASH_SUBSHELL"
doesn't prove anything if -c
summons a subshell or not and that the guy who told you that it could mislead since the variables may be substituted is correct.
Nevertheless, my own test showed that Bash really doesn't summon a subshell with it (-c
).