linux管道

Linux下管道学习

管道是我们平日使用Shell时常用的一种功能,它很神奇,能像搭乐高积木一样,将几个不同命令组成为一个整体命令。这种强大的灵活性,可以满足我们完成相当复杂的任务。

今天通过学习,Maxiee 也有点理解这种技术是怎样实现的了,真的很巧妙!

1. 管道是什么(形象角度)

书上有一张图,表达地很生动形象:

linux管道一个程序的输出,本来是输出到标准输出上的,如果我们不做手脚的话,就是输出到了屏幕上。就好像一口老血喷到了屏幕上……

可是我们现在创建了个管道,我们把这个程序的输出(嘴巴)接到管道的入口,这时,喷涌而出的老血,先在管道里面奔腾流淌。

如果我们提前将管道的出口接在另一个程序的入口上(菊花?),比如sort这个程序,那么这口老血就经由管道,流经sort,最终从sort的口中喷在了屏幕上。

不说了……好恶心。

2. 管道是什么(编程角度)

站在这一角度,管道就是两个描述符,分别代表管道的两个口。注意,管道是单向的,入口和出口都是固定的。

创建管道也很简单,我们首先要创建一个数组:int pipefd[2]; 用来盛放两个描述符。然后我们调用pipe 函数创建管道:pipe(pipefd);

创建完成后,我们的数组pipefd 就有了内容,就是这两个描述符,第0号代表出口,第1号代表入口。我们可以写一个程序,先从屏幕上读用户的一段输入,再将其顺着入口写入,再从出口里读内容,最终远原本本地输出在屏幕上。

3. 如何实现Shell 里的那种管道功能?

我们会发现,前述的跟我们在Shell 里用到的不太一样,在前述中,我们只提了描述符,却没有提链接两个程序。

这是因为,前述的,只是管道的概念,而我们在Shell里用到的功能,是对这个概念的扩展。

试想我们现在想写一个程序,实现who | sort ,我们在主进程里先定义一个管道,然后创建子进程,父进程将管道的入口重定义到自己的标准输出上,这里用到了I/O 重定向。在子进程中,再将管道的标准出重定义到子进程的标准输入上。

注意,重定向后,数组pipefd里的两个描述符就没有用了,关掉即可。

之后,主进程运行who,子进程运行sort。