Classic C.在execvp函数,stdin和stdout重定向中使用管道

我想使用管道和execvp函数在我的Linux C程序中模拟bash。 例如

ls -l | wc -l 

有我的计划:

 if(pipe(des_p) == -1) {perror("Failed to create pipe");} if(fork() == 0) { //first fork close(1); //closing stdout dup(des_p[1]); //replacing stdout with pipe write close(des_p[0]); //closing pipe read close(des_p[1]); //closing pipe write if(execvp(bash_args[0], bash_args)) // contains ls -l /* error checking */ } else { if(fork() == 0) { //creating 2nd child close(0); //closing stdin dup(des_p[0]); //replacing stdin with pipe read close(des_p[1]); //closing pipe write close(des_p[0]); //closing pipe read if(execvp(bash_args[another_place], bash_args)) //contains wc -l /* error checking */ } close(des_p[0]); close(des_p[1]); wait(0); wait(0); } 

这段代码实际上运行,但是没有做正确的事情。 这段代码出了什么问题? 这不起作用,我不知道为什么。

您需要关闭父级中的管道fds,否则子级将无法接收EOF,因为管道仍然可以在父级中写入。 这将导致第二个wait()挂起。 适合我:

 #include  #include  int main(int argc, char** argv) { int des_p[2]; if(pipe(des_p) == -1) { perror("Pipe failed"); exit(1); } if(fork() == 0) //first fork { close(STDOUT_FILENO); //closing stdout dup(des_p[1]); //replacing stdout with pipe write close(des_p[0]); //closing pipe read close(des_p[1]); const char* prog1[] = { "ls", "-l", 0}; execvp(prog1[0], prog1); perror("execvp of ls failed"); exit(1); } if(fork() == 0) //creating 2nd child { close(STDIN_FILENO); //closing stdin dup(des_p[0]); //replacing stdin with pipe read close(des_p[1]); //closing pipe write close(des_p[0]); const char* prog2[] = { "wc", "-l", 0}; execvp(prog2[0], prog2); perror("execvp of wc failed"); exit(1); } close(des_p[0]); close(des_p[1]); wait(0); wait(0); return 0; } 

阅读waitfunction的function。 它会等到一个子进程存在。 在你开始第二个孩子之前,你正在等待第一个孩子退出。 第一个孩子可能不会退出,直到有一些进程从管道的另一端读取。