我正在尝试编写一个应该用作“printenv | sort | less”的程序。然而,最后一个管道减少不起作用。我可以使用预期的结果来管道cat(显示环境变量),但是当我管道更少时,不会显示任何内容。程序运行较少但没有任何反应。如果我更多地使用该程序,则将输出捕获到窗口底部,之后没有任何反应。我不是寻呼机。
有什么想法吗?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#define WRITE 1
#define READ 0
#define DEBUG 1
int p1[2], p2[2], p3[2];
void err(char* msg){
perror(msg);
exit(EXIT_FAILURE);
}
void closePipe(int pipeEnd[2]){
if (close(pipeEnd[READ]) == -1)
err("error when closing pipe, read");
if (close(pipeEnd[WRITE]) == -1)
err("error when closing pipe, write");
}
int main(int argc, char** argv, char** envp){
int pid1, pid2, pid3;
/*Creating pipes*/
if (pipe(p1) == -1){
err("pipe1");
}
if (pipe(p2) == -1){
err("pipe2");
}
/*
if (pipe(p3) == -1){
err("pipe3");
}
*/
/*First fork*/
pid1 = fork();
if (pid1 == -1){
err("fork1");
}
/**FIRST CHILD*************PRINTENV****************/
else if (pid1 == 0){
if (dup2(p1[WRITE],STDOUT_FILENO)== -1){
err("dup2 miss");
}
closePipe(p2);
closePipe(p1);
if (execlp("printenv", "printenv", NULL) == -1){
err("execlp printenv does not like you!");
}
}
/**PARENT*******************************************/
else {
pid2 = fork();
if (pid2 == -1){
err("fork2");
}
/**SECOND*CHILD***********SORT*******************/
else if (pid2 == 0){
if (dup2(p1[READ],STDIN_FILENO) == -1){
err( "dup2 p1 read" );
}
if (dup2(p2[WRITE], STDOUT_FILENO) == -1){
err("dup2 p2 write");
}
closePipe(p2);
closePipe(p1);
if (execlp("sort", "sort", NULL) == -1){
err("execlp sort does not like you!");
}
}
/**PARENT*****************************************/
else {
pid3=fork();
if (pid3 == -1){
err("fork3");
}
/**THIRD CILD***************LESS****************/
else if (pid3 == 0){
if (dup2(p2[READ], STDIN_FILENO) == -1){
err("err dup2 read");
}
closePipe(p2);
closePipe(p1);
char *args4exec[] = {"less", NULL};
if (execvp(args4exec[0], args4exec) == -1){
err("err in exelp pager");
}
}
}
}
return 0;
}
答案 0 :(得分:5)
两件事。首先,在父母中你还需要关闭管道。其次,您的父进程应该在退出之前等待less
进程完成。尝试将其添加到您的代码中:
/* ... */
closePipe(p1);
closePipe(p2);
waitpid(pid3, NULL, 0);
return 0;
}
第一个问题导致孩子永远无法正确接收EOF,而第二个问题会导致less
立即退出,因为父母会离开。