简体   繁体   English

bash子外壳会产生新的bash进程吗?

[英]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. 并有一个表格,列出了涉及流程: xtermbash (的孩子xterm ),以及最后三个过程( catlssort )都具有相同的PPID(父进程ID) -他们的所有儿童同样的重bash过程。

Now, I know that pipelines in bash are executed in subshells . 现在,我知道bash中的管道是在subshel​​l中执行的。 I have always thought that this subshell thing meant that there was an extra bash process for each subshell. 我一直以为,这个subshel​​l的事情意味着每个subshel​​l都有一个额外的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM