Bash命令替换+参数扩展

Bash command substitution + parameter expansion

我很困惑引用和参数以及 glob 扩展应该如何在子 shell 中工作。 subshell 命令行的引用和扩展是否总是在 subshell 进程的上下文中发生?我的测试似乎证实了这一点。

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

我说的对吗?是否存在任何情况,其中父 shell 会在分叉之前以某种方式处理或评估 subshell 命令行?

解析——因此,决定如何引用哪些内容——发生在分叉之前。因为 shell 的分支副本具有其父进程内存的写时复制实例,所以它也具有解析树,并从其父进程继承此信息。

参数扩展(在您的示例中为 $foo)发生在 分叉之后。类似地,foo 的内容首先被字符串拆分和全局扩展以生成一个参数列表以传递给 subshell 内部的 echo。然后subshell运行echo,写入stdout的输出被父进程读取(原来的shell)。

命令替换结果(由 echo 写入的内容)的字符串拆分和 glob 扩展发生在父进程中,在它读取其子进程的输出作为字符串之后。