我正在阅读The TTY demystified。在"工作和会议"部分有一个用户使用xterm的例子:
$ cat
hello
hello
^Z
[1]+ Stopped cat
$ ls | sort
还有一个表格列出了所涉及的流程:xterm
,bash
(xterm
的子项)和最后三个流程(cat
,{{1 }}和ls
)都具有相同的PPID(父进程ID) - 它们都是同一sort
进程的子进程。
现在,我知道bash中的管道是在子shell 中执行的。我一直认为这个子shell事件意味着每个子shell都有一个额外的bash
进程。我的问题是:不应该有另外两个bash
流程,第一个bash
的孩子,然后bash
将成为第一个ls
的孩子,bash
将成为第二个sort
的孩子?文章中的表格是简化的,还是我对子壳的理解错了?
答案 0 :(得分:2)
直接或通过管道调用可执行文件不会生成子shell。只在子shell中显式调用它(通过(...)
,$(...)
等)就可以了。
答案 1 :(得分:2)
程序在子进程中执行,但这些不是子shell。 shell会分叉子,根据需要重定向标准输入/输出/错误,然后立即调用execv()
来执行程序。
在很短的时间内,子进程仍在运行bash
,但我们不认为这是一个子shell,因为它没有执行任何shell命令处理 - 这一切都是在原始的shell,孩子只是启动外部程序(好像通过明确的exec
来完成ls
之类的命令。
对于管道,如果任何命令是shell内置命令,则它们在子shell中运行。所以如果你这样做:
ls | read var
它将创建两个子进程。一个孩子将运行ls
,另一个孩子将执行子read var
。