首页 > 解决方案 > 带有 fork 和 dup2 的管道命令

问题描述

我编写了以下代码以通过管道传输两个命令:

#include <stdlib.h>
#include <unistd.h>

char    *program_1[3] = {"/bin/cat", "/dev/random", NULL};
char    *program_2[2] = {"/bin/ls", NULL};
char    *program_3[2] = {"/usr/bin/sort", NULL};

int main(void)
{
    int fd[2];
    int pid;

    pipe(fd);
    if ((pid = fork()) == 0) //Child process
    {
        dup2(fd[1], STDOUT_FILENO);
        close(fd[0]);
        execve(program_3[0], program_3, NULL);
    }
    else if (pid > 0) //Parent process
    {
        dup2(fd[0], STDIN_FILENO);
        close(fd[1]);
        execve(program_2[0], program_2, NULL);
    }
    return (EXIT_SUCCESS);
}

每对 program_x / program_y 其中 x != y 工作正常,除了这一对。当我通过管道将 sort 输入 ls 时,ls 会在 stdout 上很好地打印其输出,但随后 sort 会抛出此错误:sort: Input/output error.

当我输入sort | lsbash 时,它会打印 ls 结果作为我的程序,然后等待输入。

我做错了吗?

编辑:我正在尝试重新实现 shell 的行为

标签: credirectprocesspipefile-descriptor

解决方案


问题是,当ls完成时,父进程将退出,这将关闭管道的读取端,这将导致错误传播到管道的写入端,被检测到sort并写入错误消息。

它不会在 shell 中发生是因为 shell 处理管道的方式与您的简单示例程序不同,并且它保持管道的右侧打开并运行(可能在后台),直到您将EOF( Ctrl-D) 传递给sort程序。


推荐阅读