【问题标题】:What happend when I call execve() after using dup2() to redirect stdin?在使用 dup2() 重定向标准输入后调用 execve() 时发生了什么?
【发布时间】:2015-11-26 16:34:58
【问题描述】:

我正在模拟一个迷你版的 shell。当谈到用管道执行程序时,有些事情让我感到困惑。我学习了 fork()、execve()、pipe() 和 dup2()。我想我可以调用 pipe() 来构建一个未命名的管道,然后 fork(),然后使用 dup2() 将标准输出重定向到管道的写入端,使用 execve() 运行目标程序。对于第二个程序,我可以将标准输入重定向到管道的读取端,然后输出回原始的标准输出,然后使用 execve() 运行目标。但实际上,当我使用“ls -l”作为第一个程序,使用“wc -l”作为第二个程序时,它失败了。但是,如果第二个是“猫”,它就可以正常工作。那么,当我在使用 dup2() 重定向标准输入后调用 execve() 时发生了什么?还是我的程序有其他问题?

更新:我发布了一些用于验证我的想法的代码。就这个。 更重要的是,我没有使用 waitpid() 来确保这些东西按顺序运行。

int fd[2];

int main(int argc, char **argv, char **envp) {
    int fd[2];
    pipe(fd);
    int sfd[2];
    sfd[1] = dup(STDOUT_FILENO);
    sfd[0] = dup(STDIN_FILENO);
    int pid;

    pid = fork();
    if (pid == 0) {
        // child
        dup2(fd[1], STDOUT_FILENO);
        close(fd[0]);
        close(fd[1]);
        char *cmd[] = {
            "/usr/bin/ls", "-l", NULL
        };
        execve("/usr/bin/ls", cmd, envp);
    } else {
        // parent
        int status;
        waitpid(pid, &status, 0);
    }

    pid = fork();
    if (pid == 0) {
        // child
        //dup2(fd[1], STDOUT_FILENO);
        dup2(fd[0], STDIN_FILENO);
        close(fd[0]);
        close(fd[1]);
        char *cmd[] = {
            "/usr/bin/wc", "-l", NULL
        };
        execve("/usr/bin/wc", cmd, envp);
    } else {
        // parent
        int status;
        //waitpid(pid, &status, 0);
    }

    /*pid = fork();
    if (pid == 0) {
        // child
        dup2(fd[0], STDIN_FILENO);
        close(fd[0]);
        close(fd[1]);
        char *cmd[] = {
            "/usr/bin/wc", "-l", NULL
        };
        execve("/usr/bin/wc", cmd, envp);
    } else {
        // parent
        int status;
        //waitpid(pid, &status, 0);
    }*/


    return 0;
}

【问题讨论】:

  • 什么程序?贴一些代码。
  • 我已经发布了一些。谢谢:D

标签: c linux shell


【解决方案1】:

“失败”是什么意思?

如果我尝试,我会得到:

/usr/bin/wc: standard input: Input/output error
1

那是因为ls 不在我系统上的/usr/bin 中:

$ which wc cat ls
/usr/bin/wc
/bin/cat
/bin/ls

如果我解决了这个问题,我会得到:

10

作为我的输出。

【讨论】:

  • 我在 /usr/bin/ 中有 ls :( 但该代码在我的 Arch Linux 上无法运行。困惑。
猜你喜欢
  • 2018-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-19
  • 2022-11-10
  • 1970-01-01
相关资源
最近更新 更多