为什么不能直接用管道输出替换stdout?

Why is it not possible to replace stdout with pipe output directly?

我想将子进程的输出通过管道传输到父进程的 stdout。我知道还有其他方法可以做到这一点,但为什么不能将管道的读取端复制到 stdout为什么程序不打印写入管道写入端的内容?

这里我有一个最小的例子(没有任何子进程)我正在尝试做的事情。我希望在 运行 时在输出中看到 test,但程序什么都不输出。

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

int main(void) {
    int fds[2];
    if(pipe(fds) == -1) {
        perror("pipe");
        exit(EXIT_FAILURE);
    }

    if(write(fds[1], "test", 5) == -1) {
        perror("write");
        exit(EXIT_FAILURE);
    }

    if(dup2(fds[0], STDOUT_FILENO) == -1) {
        perror("dup2");
        exit(EXIT_FAILURE);
    }

    return 0;
}

管道是两个共享缓冲区和一些锁定或控制语义的“文件”。当您写入管道时,数据被放入缓冲区。当您从管道读取时,数据是从缓冲区中获取的。

管道中没有任何东西将数据移动到某个输出设备。

如果您使用 dup2 将管道的读取端复制到标准输出文件描述符(编号 1)中,那么您所拥有的只是文件描述符 1 上的管道读取端。这意味着你可以对文件描述符1发出读操作,系统将从管道中给你的程序数据。

文件描述符 1 在这方面没有什么“特别”的。将任何文件放在文件描述符 1 上不会导致该文件自动发送到任何地方。标准输出的正常工作方式是打开一个终端或某个选定的输出文件或文件描述符 1 上的其他设备,然后通过写入文件描述符 1 将内容发送到该设备或文件。操作系统不会自动写入内容文件描述符 1;你必须发出写操作。