bash子shell是否会产生一个新的`bash`进程?

时间:2014-12-27 20:12:07

标签: bash subshell

我正在阅读The TTY demystified。在"工作和会议"部分有一个用户使用xterm的例子:

$ cat
hello
hello
^Z
[1]+  Stopped                 cat
$ ls | sort

还有一个表格列出了所涉及的流程:xtermbashxterm的子项)和最后三个流程(cat,{{1 }}和ls)都具有相同的PPID(父进程ID) - 它们都是同一sort进程的子进程。

现在,我知道bash中的管道是在子shell 中执行的。我一直认为这个子shell事件意味着每个子shell都有一个额外的bash进程。我的问题是:不应该有另外两个bash流程,第一个bash的孩子,然后bash将成为第一个ls的孩子,bash将成为第二个sort的孩子?文章中的表格是简化的,还是我对子壳的理解错了?

2 个答案:

答案 0 :(得分:2)

直接或通过管道调用可执行文件不会生成子shell。只在子shell中显式调用它(通过(...)$(...)等)就可以了。

答案 1 :(得分:2)

程序在子进程中执行,但这些不是子shell。 shell会分叉子,根据需要重定向标准输入/输出/错误,然后立即调用execv()来执行程序。

在很短的时间内,子进程仍在运行bash,但我们不认为这是一个子shell,因为它没有执行任何shell命令处理 - 这一切都是在原始的shell,孩子只是启动外部程序(好像通过明确的exec来完成ls之类的命令。

对于管道,如果任何命令是shell内置命令,则它们在子shell中运行。所以如果你这样做:

ls | read var

它将创建两个子进程。一个孩子将运行ls,另一个孩子将执行子read var