2

我正在阅读The TTY demystified。在“作业和会话”部分中,有一个用户使用 xterm 的示例:

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

并且有一个表格列出了所涉及的进程:xtermbash( 的子进程xterm)和最后三个进程(catlssort)都具有相同的 PPID(父进程 ID)——它们都是同一进程的子bash进程。

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

4

2 回答 2

3

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

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

在管道的情况下,如果任何命令是 shell 内置的,它们会在子 shell 中运行。所以如果你这样做:

ls | read var

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

于 2014-12-27T20:19:26.773 回答
2

调用可执行文件,无论是直接调用还是通过管道调用,都不会产生子shell。只有在子 shell 中显式调用它(通过(...)$(...)等)才会这样做。

于 2014-12-27T20:14:43.660 回答