【发布时间】:2018-06-03 18:01:22
【问题描述】:
编辑:不要尝试将管道末端连接到标准输出。将管道的输入连接到标准输出,将管道的输出连接到标准输入。
我想使用 pipe() 和 dup2() 将子进程的标准输出通过管道传输到其母进程的标准输出。 在我的示例中,我尝试在孩子中打印一个字符串,该字符串将其标准输出重定向到管道;然后让字符串出现在母亲的标准输出中。但是,输出永远不会出现在母进程的标准输出中。怎么回事?
代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc, char *argv[])
{
// This program should print 1, 2 and 4; but only prints 1 and 4.
int stdout_cpy = dup(1);
printf("1. stdout working\n");
int pipe1[2];
pipe(pipe1);
int pid = fork();
if (pid == 0) {
// child
dup2(pipe1[1], 1); // stdout out to pipe in
close(pipe1[0]);
fprintf(stdout, "2. This should print in the mother's stdout\n");
exit(0);
} else {
// mother
close(pipe1[1]);
dup2(pipe1[0], 1); // stdout from pipe out
}
/* 2. should print in parent's stdout... */
int status;
while (wait(&status) > 0);
printf("3. This should not print\n");
dup2(stdout_cpy, 1);
close(pipe1[0]);
printf("4. stdout redirected, done\n");
return 0;
}
输出
1. stdout working
4. stdout redirected, done
【问题讨论】:
-
你为什么要给
pipe打两次电话?你的意思是第二次拨打fork? -
在父进程中,
dup2(pipe1[0], 1)是错误的。pipe1[0]是管道的 read 端,为什么要将它复制到 write 描述符?你所做的通常是不正确的。子进程写入标准输出,而在父进程中,您需要从管道的读取端读取该输出。您不能真正从子进程直接写入父进程标准输出描述符。反正不是这样的。 -
使用不确定的对象值的未定义行为。
-
正确的做法是不使用自动存储时长不确定的对象的值。
-
而且由于您不初始化
stdout_cpy,代码int stdout_cpy; dup2(1, stdout_cpy);可能很容易失败 — 但您不检查。在上下文中,您可以使用int stdout_cpy = dup(1);。