为何无法直接用管道输出替换stdout?管道读端复制到stdout无输出的技术问询
为什么把管道读端复制到stdout后看不到预期输出?
咱们先看你写的这段代码,你往管道的写端fds[1]写入了"test",然后用dup2把管道的读端fds[0]复制到了标准输出(STDOUT_FILENO),接着程序直接退出了——问题就出在这儿!
核心误区:搞反了文件描述符的用途和操作逻辑
dup2(fds[0], STDOUT_FILENO)的作用是让标准输出这个文件描述符指向管道的读端,但管道的读端是用来读取数据的,不是用来输出的。你相当于把原本用来写数据的stdout,变成了一个只能读的“输入口”,但你的程序根本没有执行读取管道数据的操作,管道里的"test"一直待在读端的缓冲区里,程序就直接退出了,自然看不到任何输出。
而且退一步说,就算你想通过stdout输出内容,现在stdout指向的是管道读端,往这个“假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); } // 关闭写端,避免管道一直处于可写状态影响读取 close(fds[1]); char buf[10]; ssize_t n = read(fds[0], buf, sizeof(buf)); if(n == -1) { perror("read"); exit(EXIT_FAILURE); } // 把读取到的内容写到真正的标准输出 write(STDOUT_FILENO, buf, n); close(fds[0]); return 0; }
要是你原本的需求是子进程输出通过管道传到父进程的stdout,那正确的逻辑应该是:子进程把自己的stdout重定向到管道写端,父进程读取管道读端的数据,再写到自己的stdout里——这时候dup2的使用场景才是合理的。
内容的提问来源于stack exchange,提问作者Olle
相关产品推荐
相关产品推荐

