2011-02-24 269 views
11

我想了解shell如何执行管道命令?例如猫|更多。我知道,执行一个正常的命令外壳做一个分叉,执行它,然后子返回。但是shell如何在内部处理管道命令的执行?shell如何执行管道命令?

回答

12

考虑到例如cat | grep,shell首先分叉自己启动cat,然后再次分叉以开始grep

在两个新创建的进程中调用其中一个exec*函数来启动两个程序之前,棘手的部分是设置管道并重定向描述符。系统调用pipe(2)在分支之前用于返回一对描述符,这两个描述符都是子继承 - 读取结束和写入结束。

读取结束将在第一个进程(cat)中关闭,标准输出将使用系统调用dup2(2)重定向到写入结束。类似地,第二个进程(grep)中的写入结束将被关闭,stdin将被重新定向到使用dup2(2)的读取结束。

这样,两个程序都不知道管道,因为他们只是使用标准输入/输出。

+0

嗨Blagovest,我有点困惑。 grep是猫的孩子还是shell的孩子?猫如何知道它必须为grep分叉? – cppdev 2011-02-24 07:36:48

+0

你是对的,特别是bash不会创造第二个过程作为第一个过程的孩子,但是这个原理依然成立,而且这两个过程仍然是壳的孩子。 – 2011-02-24 07:41:02

4

它使用pipe系统调用设置管道,分叉两个进程而不是一个进程,并将管道的一端连接到第一个进程的stdout,另一端连接到第二个进程的stdin。

+0

你能解释一下如何将一个进程的stdout与另一个进程的stdin一起加入吗? – cppdev 2011-02-24 07:29:39

+1

@cppdev:使用'dup2',但你已经从Blagovest的答案中找到了答案。 @Downvoter:这个答案有什么问题,除了它太短? – 2011-02-24 08:52:18