在C中实现pipe道

我正在尝试在C中实现pipe道,例如 – $ ls | wc | wc $ ls | wc | wc

我写了下面的代码 –

 #include<stdio.h> #include<stdlib.h> #include <unistd.h> void run_cmd(char *cmd, int* fd_in, int* fd_out) { int c = fork(); if (c==0) { if (fd_in != NULL) { close(fd_in[1]); dup2(fd_in[0], 0); } if (fd_out != NULL) { close(fd_out[0]); dup2(fd_out[1],1); } execlp(cmd, cmd, NULL); } } int main(int argc, char **argv) { int fd_1[2], fd_2[2], i; pipe(fd_1); pipe(fd_2); run_cmd(argv[1], NULL, fd_1); for( i=2; i<argc-1; i++) { if (i%2 == 0) run_cmd(argv[i], fd_1, fd_2); else run_cmd(argv[i], fd_2, fd_1); } if (i%2 == 0) run_cmd(argv[i], fd_1, NULL); else run_cmd(argv[i], fd_2, NULL); } 

这工作正常,有两个参数,例如 – $./a.out ls wc

但是,当我尝试超过两个参数不起作用。

任何人都可以告诉我的代码有什么问题,或者其他任何方式来做到这一点。 任何帮助将不胜感激。

这几乎没有错误检查,但为什么这么复杂?

 int main (int argc, char ** argv) { int i; for( i=1; i<argc-1; i++) { int pd[2]; pipe(pd); if (!fork()) { dup2(pd[1], 1); // remap output back to parent execlp(argv[i], argv[i], NULL); perror("exec"); abort(); } // remap output from previous child to input dup2(pd[0], 0); close(pd[1]); } execlp(argv[i], argv[i], NULL); perror("exec"); abort(); } 

如果你仍然对为什么你的源不工作感兴趣(谢尔盖的解决方案是更好的反正):

问题是在父进程中不关闭fd_1的写入端。 因此, argv[1]和父母都是作曲家的作品,造成了混乱。 请不要询问更多的细节(特别是为什么如果你只使用一个管道,概率不会发生),但是如果你只是添加一个close( fd_1[1] );你的原始源代码就可以在树进程中运行close( fd_1[1] ); 第一次调用run_cmd()