簡體   English   中英

匿名管道和Grep命令

[英]Anonymous pipes and Grep command

我試圖使用匿名管道實現以下

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);
}

您在尋找“ a”還是“ a”? shell語法可能會留下雙引號。

問題是您在過程3(wc)中打開了管道#1的多余管道手柄。 在調用exec之前,請關閉所有不必要的句柄。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM