我正在尝试使用匿名管道实现以下管道:
cat filename | grep "a" | wc -c
该程序似乎挂在 grep 命令上,我不明白为什么。我尝试过其他一些命令而不是grep,并且工作得很好。
到目前为止,这是代码 ......
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define READ 0
#define WRITE 1
#define handle_errno(msg) do{perror(msg); exit(EXIT_FAILURE);}while(0);
int main(int argc, char *argv[]){
int fd1[2], fd2[2];
if(argc != 2 || !strcmp(argv[1], "--help")){
fprintf(stderr, "Usage : %s <filepath>\n", argv[0]);
exit(EXIT_FAILURE);
}
if(access(argv[1], F_OK) == -1)
handle_errno("access error");
if(pipe(fd1) == -1)
handle_errno("pipe 1 error");
if(pipe(fd2) == -1)
handle_errno("pipe 2 error");
switch(fork()){
case -1: handle_errno("fork 1 error");
case 0:
/* first child: writer on pipe1 */
if(close(fd1[READ]) == -1)
handle_errno("child 1, close error");
if(fd1[WRITE] != STDOUT_FILENO){
if(dup2(fd1[WRITE], STDOUT_FILENO) == -1)
handle_errno("child 1, dup 2 error");
if(close(fd1[WRITE]) == -1)
handle_errno("child 1, close error");
}
execlp("cat", "cat", argv[1], (char*)NULL);
handle_errno("child 1, execlp cat error");
default:
break;
}
switch(fork()){
case -1: handle_errno("fork 2 error");
case 0:
/* second child: reader on pipe1, writer on pipe2 */
if(close(fd1[WRITE]) == -1)
handle_errno("child 2, close error");
if(close(fd2[READ]) == -1)
handle_errno("child 2, close error");
if(fd1[READ] != STDIN_FILENO){
if(dup2(fd1[READ], STDIN_FILENO) == -1)
handle_errno("child 2, dup 2 error");
if(close(fd1[READ]) == -1)
handle_errno("child 2, close error");
}
if(fd2[WRITE] != STDOUT_FILENO){
if(dup2(fd2[WRITE], STDOUT_FILENO) == -1)
handle_errno("child 2, dup 2 error");
if(close(fd2[WRITE]) == -1)
handle_errno("child 2, close error");
}
execlp("grep", "grep", "\"a\"", (char*)NULL);
handle_errno("child 2, execlp grep error");
default:
break;
}
switch(fork()){
case -1: handle_errno("fork 3 error");
case 0:
/* third child: reader on pipe2 */
if(close(fd2[WRITE]) == -1)
handle_errno("child 3, close error");
if(fd2[READ] != STDIN_FILENO){
if(dup2(fd2[READ], STDIN_FILENO) == -1)
handle_errno("child 3, dup 2 error");
if(close(fd2[READ]) == -1)
handle_errno("child 3, close error");
}
execlp("wc", "wc", "-c", (char*)NULL);
handle_errno("child 3, execlp wc error");
default:
break;
}
if(close(fd1[READ]) == -1)
handle_errno("father, close error");
if(close(fd1[WRITE]) == -1)
handle_errno("father, close error");
if(close(fd2[READ]) == -1)
handle_errno("father, close error");
if(close(fd2[WRITE]) == -1)
handle_errno("father, close error");
if(wait(NULL) == -1)
handle_errno("father, wait error");
if(wait(NULL) == -1)
handle_errno("father, wait error");
if(wait(NULL) == -1)
handle_errno("father, wait error");
exit(EXIT_SUCCESS);
}
答案 0 :(得分:0)
你在寻找“一个”还是一个?双引号可能会从shell语法中遗留下来。
答案 1 :(得分:0)
问题是你在过程3(wc)中打开了管道#1的额外管道把手。在调用exec之前关闭所有不必要的句柄。