在 bash 中,当我运行以下命令时:
sh -c "<em>command</em>"
是否创建了一个子 shell 然后是 <em>command</em>
执行了吗?
我的猜测是该命令将在当前 shell 中运行,但我不确定。这个猜测来 self 已经使用以下命令进行测试的事实:
echo $BASHPID, $BASH_SUBSHELL
和
sh -c "echo $BASHPID, $BASH_SUBSHELL"
结果是一样的。但正如有人告诉我的那样,这可能有点误导,因为变量可能会在命令执行之前被替换。这是真的吗?
最佳答案
我认为通过示例可以了解情况
(在我的例子中,sh
是指向 /bin/dash
的符号链接(symbolic link))。
我为 sh
做了这个测试:
echo $$ ; sh -c 'echo $$ ; sh -c '"'"'echo $$'"'"' '
16102
7569
7570
三个不同的PID
,三个不同的shell
。 (如果有不同的 shell,则不会产生 subshell)。
对于 BASH
echo $$ $BASHPID, $BASH_SUBSHELL ; bash -c 'echo $$ $BASHPID $BASH_SUBSHELL ; bash -c '"'"'echo $$ $BASHPID $BASH_SUBSHELL '"'"' '
16102 16102, 0
10337 10337 0
10338 10338 0
三个不同的$BASHPID
没有不同的$BASH_SUBSHELL
($$
和$BASHPID
的区别见下面注释>).
如果我们在不需要重新初始化的 子 shell 中,则 $$
和 $BASHPID
应该不同。
同样,$BASH_SUBSHELL
不会递增,它始终为 0
。
所以 2 条线索再次表明没有生成新的 subshell,我们只有新的 shell。
在 man bash
(4.2.45(1)-release)中,我报告了一些关于何时生成 subshell 的相关部分:
管道中的每个命令都作为一个单独的进程执行 (即,在 subshell 中)。
如果命令被控制操作符&终止,shell执行 命令在子 shell 的后台运行。 shell 不会等待 命令结束,返回状态为0。
命令以 ; 分隔顺序执行;外壳等待每个 命令依次终止。返回状态为上一个的退出状态 命令执行。 ...
( list ) list在subshell环境中执行
{ 列表; } list 只是在当前的 shell 环境中执行。coprocess 是一个以 coproc 保留字开头的 shell 命令。协同进程在子shell...
中异步执行
$ 扩展为 shell 的进程 ID。在 () subshell 中,它扩展为 当前 shell 的进程 ID,而不是 subshell。
注意事项:
BASHPID
扩展为当前 bash 进程的进程 ID。这不同于$$
在某些情况下,例如不需要 bash 的子 shell 重新初始化。BASH_SUBSHELL
每次生成子 shell 或子 shell 环境时递增 1。初始值为0。对于单引号
''
和双引号""
的使用区别you can see this question .让我们只记住,如果您在双引号""
中编写命令,变量将通过原始 shell 的参数扩展进行评估,如果 extquote 已启用,因为它默认来自shopt
。 (cfr. 4.3.2 The shopt builtin in the Bash Reference Manual)*extquote*
If set, $'string' and $"string" quoting is performed within ${parameter} expansions enclosed in double quotes. This option is enabled by default.
您可能会发现有用的进一步引用,例如
man bash
.- bash manual 的
Shell Expansions
部分. - The double quote section或
- the Parameter Expansion The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004 Edition 中定义的 Shell 命令语言。
关于bash - 当我运行 `sh -c "command"` 时,是否创建了一个子 shell,一个新的 shell 还是这些都没有?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23951346/