我正在编写一个程序,它应该像以下unix命令一样工作:seq 2 number | awk argument | grep argument
#define READ 0
#define WRITE 1
void die(char* msg){
perror(msg);
exit(EXIT_FAILURE);
}
int main(int argc, char *argv[]) {
int seq_to_awk[2];
if(pipe(seq_to_awk) == -1)
die("pipe");
pid_t child = fork();
if(child == -1)
die("fork");
if(child == 0){
if(close(seq_to_awk[READ]) == -1)
die("close");
if(dup2(seq_to_awk[WRITE], STDOUT_FILENO) < 0)
die("dup2");
if(close(seq_to_awk[WRITE]) == -1)
die("close");
execlp("seq", "seq", "2", argv[1], NULL);
}
child = fork();
if(child == -1)
die("fork");
int awk_to_grep[2];
if(pipe(awk_to_grep) == -1)
die("pipe");
if(child == 0){
if(close(seq_to_awk[WRITE]) == -1)
die("close");
if(dup2(seq_to_awk[READ], STDIN_FILENO) < 0)
die("dup2");
if(close(seq_to_awk[READ]) == -1)
die("close");
/**/
if(close(awk_to_grep[READ]) < 0)
die("close");
if(dup2(awk_to_grep[WRITE], STDOUT_FILENO) < 0)
die("dup2");
if(close(awk_to_grep[WRITE]) == -1)
die("close");
/**/
execlp("awk", "awk", argv[2], NULL);
die("execlp");
}
if(close(seq_to_awk[READ]) == -1)
die("close");
if(close(seq_to_awk[WRITE]) == -1)
die("close");
/**/
child = fork();
if(child == -1)
die("fork");
if(child == 0){
if(close(awk_to_grep[WRITE]) == -1)
die("close");
if(dup2(awk_to_grep[READ], STDIN_FILENO) < 0)
die("dup2");
if(close(awk_to_grep[READ]) == -1)
die("close");
execlp("grep", "grep", argv[3], NULL);
die("execlp");
}
/**/
if(close(awk_to_grep[READ]) == -1)
die("close");
if(close(awk_to_grep[WRITE]) == -1)
die("close");
wait(NULL);
wait(NULL);
wait(NULL);
exit(EXIT_SUCCESS);
}
当我用命令./program 26 {print} 5
运行以下代码时,我什么也得不到,而正确的输出应该是:
5
15
25
我不明白我到底做错了什么。当我省略其中一个程序(awk或grep)时,程序会按预期运行。
问题出现在设置awk_to_grep
管道时。在创建管道之前fork
,因此实际上创建了两个独立的管道。子进程中的管道对于在此之后创建的父进程和其他子进程不可用。
将订单换成:
int awk_to_grep[2];
if(pipe(awk_to_grep) == -1)
die("pipe");
child = fork();
if(child == -1)
die("fork");