编辑:不要尝试将管道末端连接到标准输出。将管道的输入连接到stdout,将管道的输出连接到stdin。
我想使用pipe()和dup2()将子进程的stdout传递给其母进程的stdout。 在我的例子中,我尝试在子节点中打印一个字符串,它的stdout重定向到管道;然后让字符串出现在母亲的标准输出中。但是,输出永远不会出现在母进程的标准输出中。发生了什么事?
代码
#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
答案 0 :(得分:1)
这是您的代码的工作版本。为了显示子项的输出,父项必须从管道中读取它,然后将其写入自己的标准输出,这就是此代码的作用。如果没有从管道读取任何内容,写入管道的输出将不会出现在任何地方。这种变化使重复的标准输出基本上无关紧要。
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
int main(void)
{
int stdout_cpy = dup(1); // Mostly irrelevant
printf("1. stdout working\n");
int pipe1[2];
pipe(pipe1);
int pid = fork();
if (pid == 0)
{
// child at work
dup2(pipe1[1], 1); // stdout out to write end of pipe
close(pipe1[0]); // Close both ends of the pipe!
close(pipe1[1]); // Close both ends of the pipe!
printf("2. This should be read by parent from stdin and be printed to the parent's stdout\n");
exit(0);
}
/* Parent at work */
dup2(pipe1[0], 0); // stdin from from read end of pipe
close(pipe1[0]); // Close both ends of the pipe!
close(pipe1[1]); // Close both ends of the pipe!
// Read data written on pipe by child, and write to stdout
char buffer[512];
int nbytes = read(0, buffer, sizeof(buffer));
if (nbytes > 0)
write(1, buffer, nbytes);
/* 2. should print in parent's stdout... */
int status;
int corpse;
while ((corpse = wait(&status)) > 0)
printf("%d: child %d exited with status 0x%.4X\n", (int)getpid(), corpse, status);
printf("3. This should print too\n");
dup2(stdout_cpy, 1); // Mostly irrelevant
//close(pipe1[0]); // Long since closed
close(stdout_cpy); // No longer needed (closed on exit anyway)
printf("4. stdout redirected, done\n");
return 0;
}
示例输出:
1. stdout working
2. This should be read by parent from stdin and be printed to the parent's stdout
8008: child 8009 exited with status 0x0000
3. This should print too
4. stdout redirected, done
或者,如果您只想让孩子的输出与父母的输出显示在同一设备上,那么根本就不要使用管道;孩子将继承父母的标准输出,并且可以在没有任何额外帮助的情况下写入。