I'm confused how the quoting and parameter and glob expansion is supposed to work in a subshell. Does the quoting and expansions of the subshell command line always happen in the context of the subshell process? My test seems to confirm this.
Tuomas@DESKTOP-LI5P50P MINGW64 ~/shell/test1/test
$ ls
a b c
Tuomas@DESKTOP-LI5P50P MINGW64 ~/shell/test1/test
$ echo "$(echo *)"
a b c
# The subshell expands the * glob
Tuomas@DESKTOP-LI5P50P MINGW64 ~/shell/test1/test
$ echo $(echo '*')
a b c
# The subshell outputs literal *, parent shell expands the * glob
Tuomas@DESKTOP-LI5P50P MINGW64 ~/shell/test1/test
$ echo $(echo "*")
a b c
# The subshell outputs literal *, parent shell expands the * glob
Tuomas@DESKTOP-LI5P50P MINGW64 ~/shell/test1/test
$ echo "$(echo '*')"
*
# The subshell outputs literal *, parent shell outputs literal *
Tuomas@DESKTOP-LI5P50P MINGW64 ~/shell/test1/test
$ foo=bar
Tuomas@DESKTOP-LI5P50P MINGW64 ~/shell/test1/test
$ echo "$(echo $foo)"
bar
# The subshell expands variable foo
Tuomas@DESKTOP-LI5P50P MINGW64 ~/shell/test1/test
$ echo $(echo '$foo')
$foo
# The subshell outputs literal $foo
Tuomas@DESKTOP-LI5P50P MINGW64 ~/shell/test1/test
$ echo $(echo "$foo")
bar
# The subshell expands variable foo
Tuomas@DESKTOP-LI5P50P MINGW64 ~/shell/test1/test
$ echo "$(echo '$foo')"
$foo
# The subshell outputs literal $foo
Am I correct? Is there any scenarios, where parents shell will somehow process or evaluate the subshell command line before forking?
The parsing -- thus, the determination of which content is quoted how -- happens before the fork. Because the forked-off copy of the shell has a copy-on-write instance of the memory of its parent process, it also has the parse tree, and inherits this information from its parent.
The parameter expansion (of $foo
in your examples) happens after the fork. Similarly, the contents of foo
are first string-split and glob-expanded to generate an argument list to pass to echo
inside the subshell. Then that subshell runs echo
, and the output written to stdout is read by the parent process (the original shell).
String-splitting and glob expansion of the command substitution's result (the content written by echo
) happens back in the parent process, after it read the output of its child as a string.