[英]Does a bash subshell spawn a new `bash` process?
I am reading The TTY demystified . 我正在阅读《神秘的TTY》 。 In the "Jobs and sessions" section there is an example of a user using an xterm:
在“作业和会话”部分中,有一个用户使用xterm的示例:
$ cat
hello
hello
^Z
[1]+ Stopped cat
$ ls | sort
And there is a table listing the processes involved: xterm
, bash
(child of the xterm
), and the three last processes ( cat
, ls
and sort
) all have the same PPID (parent process ID) -- they are all children of the same bash
process. 并有一个表格,列出了涉及流程:
xterm
, bash
(的孩子xterm
),以及最后三个过程( cat
, ls
和sort
)都具有相同的PPID(父进程ID) -他们的所有儿童同样的重bash
过程。
Now, I know that pipelines in bash are executed in subshells . 现在,我知道bash中的管道是在subshell中执行的。 I have always thought that this subshell thing meant that there was an extra
bash
process for each subshell. 我一直以为,这个subshell的事情意味着每个subshell都有一个额外的
bash
进程。 My question is: shouldn't there be another two bash
processes, both children of the first bash
, and then ls
would be a child of the first bash
, and sort
would be a child of the second bash
? 我的问题是:难道不应该有另外两个
bash
进程,第一个bash
两个子进程,然后ls
是第一个bash
的子进程,而sort
是第二个bash
的子进程吗? Is the table in the article simplified, or is my understanding of subshells wrong? 本文中的表格是否已简化,或者我对子外壳的理解不正确?
Invoking an executable, whether directly or via a pipe, does not spawn a subshell. 无论是直接调用还是通过管道调用可执行文件,都不会生成子外壳。 Only explicitly invoking it within a subshell (via
(...)
, $(...)
, and so on) does so. 只有在子外壳中显式调用它(通过
(...)
, $(...)
等)才能这样做。
Programs are executed in child processes, but these are not subshells. 程序在子进程中执行,但它们不是子shell。 The shell forks a child, redirects standard input/output/error as necessary, and then immediately calls
execv()
to execute the program. Shell派生一个孩子,根据需要重定向标准输入/输出/错误,然后立即调用
execv()
来执行程序。
For a very brief period the child process is still running bash
, but we don't consider this a subshell because it's not doing any shell command processing -- that was all done in the original shell, and the child is just starting up the external program (as if via an explicit exec
for commands like ls
). 在很短的时间内,子进程仍在运行
bash
,但我们不将其视为子shell,因为它没有执行任何shell命令处理-全部在原始shell中完成,而子进程只是在启动外部程序(就像通过像ls
这样的命令的显式exec
)。
In the case of a pipeline, if any of the commands are shell built-ins, they run in a subshell. 对于管道,如果任何命令是Shell内置的,则它们在子Shell中运行。 So if you do:
因此,如果您这样做:
ls | read var
it will create two child processes. 它将创建两个子进程。 One child will run
ls
, the other will be a subshell executing read var
. 一个孩子将运行
ls
,另一个孩子将是执行read var
的子shell。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.