Bash命令替换+参数扩展

时间:2018-08-14 16:43:11

标签: bash shell scripting subshell

我对引号,参数和glob扩展应该如何在子shell中工作感到困惑。 subshel​​l命令行的引用和扩展是否总是在subshel​​l进程的上下文中发生?我的测试似乎证实了这一点。

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在分叉之前会以某种方式处理或评估subshel​​l命令行吗?

1 个答案:

答案 0 :(得分:2)

解析-因此,确定引用哪些内容的方式-在之前发生。由于外壳的分叉副本具有其父进程的内存的写时复制实例,因此它也具有解析树,并从其父级继承此信息。

参数扩展(在您的示例中为$foo)发生在 分支之后。类似地,foo的内容首先进行字符串拆分和glob扩展,以生成一个参数列表,以传递到子Shell内的echo。然后,该子Shell运行echo,并且父进程(原始Shell)读取写入stdout的输出。

命令替换结果(由echo编写的内容)的字符串拆分和glob扩展发生在父进程中,它以字符串的形式读取了其子级的输出。