使用简单的管道unix

时间:2014-12-02 19:58:58

标签: c unix pipeline

由于某些原因我无法正确使用,我想通过管道调用“ls -l”和“tail -n 2”,这样文件列表中的最后两个文件就会显示出来。 这是代码:

int pipefd[2];
pipe(pipefd);
int id = fork();

if(id == 0)
{
    dup2(pipefd[1], 1);
    close(pipefd[1]);
    execvp("ls", (char*[]){"ls", "-l", NULL});
}
else 
{
    dup2(pipefd[0], 0);
    execvp("tail", (char*[]){"tail", "-n", "2", NULL});
    waitpid(id, NULL, 0);
    close(pipefd[0]);
}

return 0;

以下代码有什么问题?我觉得我在这里有误会,我也经常搜索,在网上找不到答案......

3 个答案:

答案 0 :(得分:1)

通过调用:

dup2(pipefd[1], 1); close(pipefd[1]);

在子进程中,您正在关闭已关闭的pipefd[1],因此close(pipefd[1]);无效。您还应该关闭子进程中的pipefd[0]。同样适用于父进程。因此,您的代码应按如下方式进行编辑:

int pipefd[2];
pipe(pipefd);
int id = fork();

if(id == 0)
{
    dup2(pipefd[1], 1);
    close(pipefd[0]);
    execvp("ls", (char*[]){"ls", "-l", NULL});
}
else 
{
    dup2(pipefd[0], 0);
    close(pipefd[1]);
    execvp("tail", (char*[]){"tail", "-n", "2", NULL});
    waitpid(id, NULL, 0);
}

答案 1 :(得分:0)

tail替换为cat,您将看到cat传递和打印的文件列表,但未达到EOF。您需要关闭未使用的pipefd描述符:

请注意,仅当waitpid的{​​{1}}失败时才会访问此计划中的execvp

固定代码:

tail

答案 2 :(得分:0)

试试这个(注意额外关闭)......:

    int pipefd[2];
    pipe(pipefd);

    int id = fork();

    if(id == 0)
    {
        dup2(pipefd[1], 1);
        close(pipefd[1]);
        close(pipefd[0]);
        execvp("ls", (char*[]){"ls", "-l", NULL});
    }
    else
    {
        dup2(pipefd[0], 0);
        close(pipefd[0]);
        close(pipefd[1]);
        execvp("tail", (char*[]){"tail", "-n", "2", NULL});
        waitpid(id, NULL, 0);
    }

    return 0;