No, the subshell was created first.
A shell execution environment contains shell parameters set by variable assignments and environment variables. A subshell environment was created by duplicating the shell environment, so it contains all the variables of the current shell environment.
See the example:
$ b=1
$ c=$(b=2; echo "$b")
$ echo "$c"
2
The output is 2
instead of 1
.
A subshell environment created by command substitution is different with a shell environment created by calling the shell executable.
When you call the shell as:
$ bash -c :
the the current shell used execve() to create new shell process, something like:
execve("/bin/bash", ["bash", "-c", ":"], [/* 64 vars */]) = 0
the last argument passed to execve
contains all the environment variables.
That's why you need to export the variables to push it to the environment variables, which will be included in subsequently executed commands:
$ a=; export a
$ strace -e execve bash -c :
execve("/bin/bash", ["bash", "-c", ":"], [/* 65 vars */]) = 0
+++ exited with 0 +++
Notice the environment variables change from 64 to 65. And variables which are not exported will not be passed to new shell environment:
$ a=; b=; export a
$ strace -e execve bash -c :
execve("/bin/bash", ["bash", "-c", ":"], [/* 65 vars */]) = 0
+++ exited with 0 +++
Notice the environment variables are still 65.
In command substitution, the shell used fork() to create new shell process, which just copied the current shell environment - which contains both variables set and environment variables.
bash
? – Tim Feb 11 '16 at 20:39bash -c <command>
? – Tim Feb 11 '16 at 20:45bash -c <command>
". There is a very slight different: When you execute a shell script, the kernel reads the first line, sees the "sh-bang" and tries to execute the program specified after that with the script itself as the first argument. Thus, it's the difference betweenbash <scriptfile>
andbash -c <scriptfile>
. In the second form, bash will do anexec
with<scriptfile>
as an argument, and so ultimately, you getbash <scriptfile>
again, but after an additional exec. – Otheus Feb 12 '16 at 00:12