这个程序用无名管道实现命令 cat /etc/passwd | grep root
其实在终端命令中 | 就是一个管道 cat /etc/passwd会把结果打印到标准输出 ,grep root 会把结果从标准输入
实现流程:
1.父进程生产两个子进程(进程扇的概念)
2.子进程A:
a: 把标准输出定位到管道写端,因为此时cat /etc/passwd的结果原本要输出到标准输出,这里我们必须定位到管道写段,相
当与执行cat /etc/passwd后就往管道写入了数据
b: 调用execvp执行 cat /etc/passwd命令
3.子进程B:
a: 把标准输入重定向到管道读端,因为原本 grep root 会从标准输入读取数据,这里需要重定向到管道读端去读取数据
b: 调用execvp执行 grep root 从管道读端读取数据,并显示在标准输出上
其源码如下:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
char *cmd1[3]={"/bin/cat","/etc/passwd",NULL};
char *cmd2[3]={"/bin/grep","root",NULL};
int main(void)
{
int fd[2];
if(pipe(fd)<0){
perror("pipe error");
exit(1);
}
int i=0;
pid_t pid;
for(;i<2;i++)
{
pid=fork();
if(pid<0)
{
perror("fork error");
exit(1);
}
else if(pid==0)
{
if(i==0){//往管道写入数据
close(fd[0]);
//标准输出重定向管道写段
if(dup2(fd[1],STDOUT_FILENO)!=STDOUT_FILENO)
{
perror("dup2 error");
}
if(execvp(cmd1[0],cmd1)<0)
{
perror("execvp error");
exit(1);
}
break;
}
if(i==1){
close(fd[1]);
//标准输入重定向到读端
if(dup2(fd[0],STDIN_FILENO)!=STDIN_FILENO)
{
perror("dup2 error");
}
if(execvp(cmd2[0],cmd2)<0)
{
perror("execvp error");
exit(1);
}
break;
}
}
else
{
if(i==1)
{
close(fd[0]);
close(fd[1]);
wait(0);
wait(0);
}
}
}
return 0;
}
其实验结果如下:
root:x:0:0:root:/root:/bin/bash