使用shell时,我们常使用以下这类命令:
who|sort > userlist
含义为shell同时执行who和sort,将who的输出字节送到sort的输出,最后将sort的输出送到userlist文件。
实现上述功能的关键就在于管道和重定向。
重定向
(1)unix进程使用文件描述符0,1,2作为标准输入,输出和错误的通道,并且通常通过shell运行系统工具时,stdin,stdout,stderr连接在终端上,工具从键盘读取数据并且把输出和错误信息写到屏幕。
(2)当进程请求一个新的文件描述符时,系统内核将最低可用的文件描述符赋给它。
利用这个特性我们先close(0),fd = open(“”,O_RDONLY);,就可以重定位到标准输入,即新打开的文件被当做标准输入。
管道
shell首先创建管道,然后调用fork创建两个新进程,再将标准输入和输出重定向到创建的管道,最后再通过exec来执行两个程序。
./pipe who sort 与 who|sort相等
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#define oops(m,x) { perror(m); exit(x);}
int main (int ac,char **av)
{
int thepipe[2],newfd,pid;
if(ac != 3){
fprintf(stderr,"usage:pipe cmd1 cmd2\n");
exit(1);
}
if(pipe(thepipe) == -1)
oops("cannot get a pipe",1);
if((pid = fork()) == -1)
oops("cannot fork",2);
if(pid > 0){
close(thepipe[1]);
if(dup2(thepipe[0],0) == -1)
oops("could not redirect stdin",3);
close(thepipe[0]);
execlp(av[2],av[2],NULL);
oops(av[2],4);
}
close(thepipe[0]);
if(dup2(thepipe[1],1) == -1)
oops("could not redirect stdout",4);
close(thepipe[1]);
execlp(av[1],av[1],NULL);
oops(av[1],5);
}