2012-01-06 7 views
1

匿名パイプとgrepコマンド

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

問題は、プロセス#3(wc)で開いているパイプ#1の余分なパイプハンドルが残っていることです。閉じるすべて execを呼び出す前に不要なハンドル。

+0

ええ、ただ気づいた。また、私は "cat process"のpipe#2のためにオープンハンドルを残しました。とにかくありがとうございました。 – user996922

0

あなたが "A" またはお探しですか?二重引用符は、シェルの構文から残されるかもしれません。

+0

シェルはaと "a"に対して同じ出力を生成します。 意味: 'cat filename | grep \ "a \" ' – alfasin

+0

execlp経由でgrepに二重引用符を渡してもうまくいきません。 – Joshua

+0

@Joshua:execlp( "grep"、 "grep"、 "\" a \ ""、(char *)NULL)を呼び出すか、単にexeclp( "grep"、 "grep"、 "a "、(char *)NULL); – user996922