叉子和水管,我在做什么错了?

问题描述 投票:0回答:1

我正在尝试了解管道和重定向。为此,我正在做一些小程序来适应相关的系统调用。在此上,我试图在文件pipe4.c上启动cat,并将其输出通过管道传递到我随后启动的grep。它不起作用,我不明白结果,我虽然逻辑很好,但显然我用fork缺少了一些东西。我在做什么错?

这里是代码:

    #include <stdio.h>
    #include <fcntl.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/wait.h>
    #define BUFF_SIZE 4092

    //redirecting the output of a program ('cat' here)
    //to the stdin of another program ('grep' here)
    void    err_handler(char *msg)
    {
        perror(msg);
        exit(EXIT_FAILURE);
    }

    int main(void)
    {
        //creating a pipe to communicate between the child processes
        int p[2];
        if (pipe(p) < 0)
            err_handler("pipe error: ");
        /*
        ** forking for cat
        */
        pid_t cat_pid;
        if ((cat_pid = fork()) < 0)
            err_handler("fork error: ");
        if (cat_pid)
            close(p[1]);
        if (!cat_pid) {
            printf("===CAT===\n");
            dup2(p[1], STDOUT_FILENO);
            close(p[0]);
            close(p[1]);
            execl("/bin/cat", "cat", "pipe4.c", NULL);
            exit(EXIT_SUCCESS);
        }
        /*
        ** forking for grep
        */
        pid_t grep_pid;
        if ((grep_pid = fork()) < 0)
            err_handler("fork_error: ");
        if (grep_pid)
            wait(&grep_pid);
        if (!grep_pid) {
            printf("===GREP===\n");
            dup2(p[0], STDIN_FILENO);
            close(p[0]);
            close(p[1]);
            execl("/bin/grep", "grep", "\"err_handler\"", NULL);
            exit(EXIT_SUCCESS);
        }
        return 0;

}

我只能在我的终端上得到它:

> pom@parrot ~/dev/19/syscall> sudo ./a.out 
> ===GREP===
> ===CAT===
> ===GREP===

每次执行时,这些行的打印顺序都会改变。我期望的显然是在pipe4.c文件中所有包含“ err_handler”的行,就像我直接在shell中执行的一样:

> pom@parrot ~/dev/19/syscall> cat pipe4.c | grep "err_handler"
> void  err_handler(char *msg)      err_handler("pipe error: ");
>       err_handler("fork error: ");            err_handler("creat error: ");
>               err_handler("read error: ");
>               err_handler("write error:");
c unix pipe fork system-calls
1个回答
0
投票

(有(我认为!)3个主要问题。

1)您没有正确使用等待。我建议改用waitpid。2)至少在我的系统上,/ bin / grep不存在。它是/ usr / bin / grep。但是由于exec失败时您将返回EXIT_SUCCESS,所以您看不到它。您应将execl (...); exit( EXIT_SUCESS)替换为execl(...); perror("execl"); exit(EXIT_FAILURE);3)您正在搜索文字引号。就好像您在运行:

grep '"err_handler"'

即生成grep时execl的参数应该是"err_handler",而不是"\"err_handler\""

© www.soinside.com 2019 - 2024. All rights reserved.