Shell如何执行管道命令?

12

我想了解shell如何执行管道命令,例如cat | more。我知道对于执行普通命令,shell会进行fork,执行该命令,然后子进程返回。但是shell如何在内部处理管道命令的执行呢?

3个回答

15

例如考虑 cat | grep,shell 首先创建一个子进程来启动 cat,然后再创建一个子进程来启动 grep

在调用 exec* 函数族中的任意一个函数来启动这两个程序的新进程之前,需要设置管道并重定向描述符。在 shell 进程中使用 pipe(2) 系统调用,在分叉之前返回一对描述符,两个子进程都会从父进程继承这些描述符 - 一个读描述符和一个写描述符。

第一个进程(cat)将关闭读描述符,并使用 dup2(2) 系统调用将标准输出重定向到写描述符。类似地,第二个进程(grep)将关闭写描述符,并使用 dup2(2) 将标准输入重定向回读描述符。

这样,两个程序都不知道有一个管道存在,因为它们只使用标准输入/输出。


嗨Blagovest,我有点困惑。grep是cat的子进程还是shell的子进程?cat如何知道它必须为grep分叉? - cppdev
你说得对,特别是bash不会将第二个进程创建为第一个进程的子进程,但原则仍然存在,两个进程仍然是shell的子进程。 - Blagovest Buyukliev

3

它使用pipe系统调用设置管道,不是一个进程而是两个进程,将管道的一端连接到第一个进程的标准输出,另一端连接到第二个进程的标准输入。


你能解释一下如何将一个进程的标准输出与另一个进程的标准输入连接起来吗? - cppdev
1
@cppdev:使用dup2,但你已经从Blagovest的答案中找到了。@Downvoter:除了太短之外,这个答案有什么问题吗? - Fred Foo

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接