坚持在C中使用多个管道

时间:2015-08-29 10:10:00

标签: c unix pipe piping

我正在编写一个程序,专门将3个程序链接在一起,等等“ls | sort | wc”。

我浏览了一下我在google上发现的有关多个管道的其他帖子,但我仍然无法弄清楚我做错了什么。被困在这一段时间了。我相信我的程序在逻辑上是正确的,但由于某种原因它不会运行。我错过了什么?

pipe(pipe1);
pipe(pipe2);

pid = fork();
if(pid > 0){
    close(pipe2[1]);
    dup2(pipe2[0], 0);
    execlp(argv[3], argv[3], NULL);
}
else if(pid == 0){
    pid2 = fork();
    if(pid2 == 0){
        close(pipe1[0]);
        dup2(pipe1[1], 1);
        execlp(argv[1], argv[1], NULL);
    }
    else if(pid2 > 0){
        close(pipe1[1]);
        dup2(pipe1[0], 0);
        close(pipe2[0]);
        dup2(pipe2[1], 1);
        execlp(argv[2], argv[2], NULL);
    }
}

2 个答案:

答案 0 :(得分:0)

您需要在父案例中每次分叉三次,并仅在子案例中执行命令。看看here

根据您的情况调整:

#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

int main(int argc, char **argv) {

  int pid;
  int pipe1[2];
  int pipe2[2];

  // create pipe1
  if (pipe(pipe1) == -1) {
    perror("bad pipe1");
    exit(1);
  }

  // fork (ps aux)
  if ((pid = fork()) == -1) {
    perror("bad fork1");
    exit(1);
  } 
  else if (pid == 0) {
    // stdin --> ps --> pipe1
    // input from stdin (already done), output to pipe1
    dup2(pipe1[1], 1);
    // close fds
    close(pipe1[0]);
    close(pipe1[1]);

    execlp(argv[1], argv[1], NULL);
    // exec didn't work, exit
    perror("bad exec ps");
    _exit(1);
  }
  // parent

  // create pipe2
  if (pipe(pipe2) == -1) {
    perror("bad pipe2");
    exit(1);
  }

  // fork (grep root)
  if ((pid = fork()) == -1) {
    perror("bad fork2");
    exit(1);
  } 
  else if (pid == 0) {
    // pipe1 --> grep --> pipe2
    // input from pipe1
    dup2(pipe1[0], 0);
    // output to pipe2
    dup2(pipe2[1], 1);
    // close fds
    close(pipe1[0]);
    close(pipe1[1]);
    close(pipe2[0]);
    close(pipe2[1]);

    execlp(argv[2], argv[2], NULL);
    // exec didn't work, exit
    perror("bad exec grep root");
    _exit(1);
  }
  // parent

  // close unused fds
  close(pipe1[0]);
  close(pipe1[1]);

  // fork (grep sbin)
  if ((pid = fork()) == -1) {
    perror("bad fork3");
    exit(1);
  } 
  else if (pid == 0) {
    // pipe2 --> grep --> stdout
    // input from pipe2
    dup2(pipe2[0], 0);
    // output to stdout (already done). Close fds
    close(pipe2[0]);
    close(pipe2[1]);

    execlp(argv[3], argv[3], NULL);
    // exec didn't work, exit
    perror("bad exec grep sbin");
    _exit(1);
  }
  // parent

  return 0;
}

答案 1 :(得分:0)

我找到了另一个解决方案,父进程处理第一个命令,将其输出写入第一个管道,并创建一个子进程,该子进程将处理第二个命令并将其输出写入第二个管道,同时该子进程将创建一个子子进程这将处理第三个命令。

命令是:ls -l | grep“ sthg”`| wc -l <​​/ p>

#include<sys/types.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include <fcntl.h>

int main(){
int p[2],p1[2];
int x,y,z;
pipe(p);
x= fork();

if (x>0){//père or parent

close(p[0]);
dup2(p[1],1);
execlp("ls","ls","-l",NULL);
close(p[1]);

}
else{ // fils du père or child of parent
pipe(p1);
z=fork();
if(z>0){ //fils du père or child of parent

close(p[1]);
close(p1[0]);
dup2(p[0],0);
dup2(p1[1],1);
execlp("grep","grep","sthg",NULL);
close(p[0]);
close(p1[1]);

}
else{ //fils du fils or sub-child

close(p[0]);
close(p[1]);
close(p1[1]);
dup2(p1[0],0);
execlp("wc","wc","-l",NULL);
close(p1[0]);

}

}
return 0;
}