c - 为什么当我在 fork() 之前使用 dup2() 时它不起作用?

标签 c shell fork dup2

我想制作一个 shell 并且我想处理多个管道。我试图了解 dup2() 和 fork 的工作原理。通常,fork()会创建一个与父进程完全相同的新子进程。但是当我在 fork 之前使用 dup2 时,它似乎无法正常工作。但是当我在子进程中使用 dup2() 时它会起作用...我不明白,因为通常 fork 会创建调用进程的副本...

有人能解释一下为什么吗?

这不起作用:

int fd = open("toto.txt", O_RDONLY);
char str[10] = {0};
int test[2] = {0, 0};
char *av[] = {"/bin/ls", NULL};

pipe(test);
dup2(test[1], 1);
if (fork() == 0) {
    execve(av[0], av, env);
}
else {
    wait(NULL);
    read(test[0], str, 10);
    write(1, str, 10);
}

但这有效:

int fd = open("toto.txt", O_RDONLY);
char str[10] = {0};
int test[2] = {0, 0};
char *av[] = {"/bin/ls", NULL};

pipe(test);
if (fork() == 0) {
    dup2(test[1], 1);
    execve(av[0], av, env);
}
else {
    wait(NULL);
    read(test[0], str, 10);
    write(1, str, 10);
}

最佳答案

原件无法正常工作,因为:

dup2(test[1], 1);
if (fork() == 0) {
    execve(av[0], av, env);
}
else {
    wait(NULL);
    read(test[0], str, 10);
    write(1, str, 10);
}

dup2 stdout 被重定向到管道之后。此重定向同时适用于父级和子级。因此,该行:

    write(1, str, 10);

将其数据写回管道,而不是原始的标准输出(已丢失)。

通过将 dup2 移至 fork() 之后,并且仅移至子进程,父进程的原始 stdout 将被保留。在这种情况下,只有子进程的标准输出会被重定向。

注意:在读取管道之前调用 wait 将适用于小管道流量(如示例中所示),但不适用于大流量。问题是管道的缓冲区有限。一旦缓冲区已满,管道就开始阻止写入。 wait 将等待子进程完成,但子进程将等待父进程读取管道。当流量足够大时,这可能会成为僵局。

关于c - 为什么当我在 fork() 之前使用 dup2() 时它不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55257628/

相关文章:

linux - 根据其他列的值创建一个新列

c - 如何在没有 gcc 编译器的情况下在 docker 中打包和发布一个简单的 c 应用程序?

c - 什么时候 char* 对于严格的指针别名是安全的?

c - 从文件读取时出现段错误

c - 为什么我的第一个子进程没有收到他 parent 的信号

c - 使用 1 个管道通过 fork() 设置四个进程

linux - CPU 能否在子进程执行时将进程保持在挂起状态 10 秒?

c - 将字符串值存储在 int 中

linux - 在 shell 脚本中使用 history 命令

linux - 如何比较文件与关键字文件并用关键字文件第 3 列中的正确字符串替换第 3 列的不匹配字符串