如何将标准输入从 child 传输到 parent?
How to pipe stdin from child to parent?
我正在尝试从 parent 进程中 exec()
一个 child 进程。在这个 child 过程中,我要求用户输入一条消息,以便 parent 过程可以将其打印出来,但我找不到办法...
到目前为止,我的代码是:
parent.c
int main(int argc, char **argv) {
int fd[2];
char line[80];
pipe(fd);
pid_t pid = (pid_t)fork();
if(pid > 0) {
waitpid(pid, NULL, 0);
close(fd[0]);
int size = read(fd[1], line, 79);
close(fd[1]);
line[size] = '[=12=]';
printf("[parent] Received \"%s\", size = %d\n", line, size);
}
else {
close(fd[1]);
close(stdin);
dup2(fd[0], stdin);
close(fd[0]);
exec("./child", 0, NULL);
}
return 0;
}
child.c
int main(int argc, char **argv) {
char line[80];
printf("[child] Enter message: ");
gets(line, 80);
printf("[child] line = %s\n", line);
return 0;
}
当我启动 parent 进程时,它显示 [child] Enter message:
但当我尝试输入内容时,即使我按下 return 键,也没有任何显示。
你知道我怎样才能让它发挥作用吗?
感谢您的帮助。
除了我评论中提到的问题外,您遇到的问题是死锁。你得到它是因为父进程等待子进程退出。但是子进程正在等待永远不会到达的输入。
那是因为在子进程中你说输入应该来自管道。
此外,在父进程中,您尝试从管道的写入端读取。
最后,只要子进程想要读取用户输入,您的程序就永远无法运行,因为所有用户输入都将转到 parent 进程。
要使其全部正常工作,您需要重新考虑您的设计,并使 parent 进程成为读取用户输入并写入管道的进程。并且子进程应该从管道读取并打印到(非管道)标准输出。或者您关闭父级中的(正常,非管道)标准输入,并在子级中写入管道(作为标准输出)。
您的代码有几个问题:
- 您将整数(低级)文件描述符和(高级)FILE * 常量混合在一起。
- 你颠倒了 stdin 和 stdout 以及通过
pipe
获得的描述符的顺序
- 当你打算重定向它时,你在 stdout 上写了一条消息(应该使用 stderr)
这是一个固定版本(我通过 fgets 更改了你的 gets,以及你的 exec 和 execl 以编译所有内容):
parent.c:
int main(int argc, char **argv) {
int fd[2];
char line[80];
pipe(fd);
pid_t pid = (pid_t)fork();
if(pid > 0) {
waitpid(pid, NULL, 0);
close(fd[1]);
int size = read(fd[0], line, 79);
close(fd[0]);
line[size] = '[=10=]';
printf("[parent] Received \"%s\", size = %d\n", line, size);
}
else {
close(fd[0]);
close(1);
dup2(fd[1], 1);
close(fd[1]);
execl("./child", NULL);
}
return 0;
}
child.c
int main(int argc, char **argv) {
char line[80];
fprintf(stderr, "[child] Enter message: ");
fgets(line, 80, stdin);
printf("[child] line = %s\n", line);
return 0;
}
我找到了解决方法。我的实际目标是在 parent 和 child 之间传递信息。我的错误是在 stdin
上 dup2
。通过这样做,当程序询问时我无法输入任何内容。所以我在 argv
中传递了文件描述符的值,我的问题就解决了。
再次感谢您的帮助!
我正在尝试从 parent 进程中 exec()
一个 child 进程。在这个 child 过程中,我要求用户输入一条消息,以便 parent 过程可以将其打印出来,但我找不到办法...
到目前为止,我的代码是:
parent.c
int main(int argc, char **argv) {
int fd[2];
char line[80];
pipe(fd);
pid_t pid = (pid_t)fork();
if(pid > 0) {
waitpid(pid, NULL, 0);
close(fd[0]);
int size = read(fd[1], line, 79);
close(fd[1]);
line[size] = '[=12=]';
printf("[parent] Received \"%s\", size = %d\n", line, size);
}
else {
close(fd[1]);
close(stdin);
dup2(fd[0], stdin);
close(fd[0]);
exec("./child", 0, NULL);
}
return 0;
}
child.c
int main(int argc, char **argv) {
char line[80];
printf("[child] Enter message: ");
gets(line, 80);
printf("[child] line = %s\n", line);
return 0;
}
当我启动 parent 进程时,它显示 [child] Enter message:
但当我尝试输入内容时,即使我按下 return 键,也没有任何显示。
你知道我怎样才能让它发挥作用吗?
感谢您的帮助。
除了我评论中提到的问题外,您遇到的问题是死锁。你得到它是因为父进程等待子进程退出。但是子进程正在等待永远不会到达的输入。
那是因为在子进程中你说输入应该来自管道。
此外,在父进程中,您尝试从管道的写入端读取。
最后,只要子进程想要读取用户输入,您的程序就永远无法运行,因为所有用户输入都将转到 parent 进程。
要使其全部正常工作,您需要重新考虑您的设计,并使 parent 进程成为读取用户输入并写入管道的进程。并且子进程应该从管道读取并打印到(非管道)标准输出。或者您关闭父级中的(正常,非管道)标准输入,并在子级中写入管道(作为标准输出)。
您的代码有几个问题:
- 您将整数(低级)文件描述符和(高级)FILE * 常量混合在一起。
- 你颠倒了 stdin 和 stdout 以及通过
pipe
获得的描述符的顺序
- 当你打算重定向它时,你在 stdout 上写了一条消息(应该使用 stderr)
这是一个固定版本(我通过 fgets 更改了你的 gets,以及你的 exec 和 execl 以编译所有内容):
parent.c:
int main(int argc, char **argv) {
int fd[2];
char line[80];
pipe(fd);
pid_t pid = (pid_t)fork();
if(pid > 0) {
waitpid(pid, NULL, 0);
close(fd[1]);
int size = read(fd[0], line, 79);
close(fd[0]);
line[size] = '[=10=]';
printf("[parent] Received \"%s\", size = %d\n", line, size);
}
else {
close(fd[0]);
close(1);
dup2(fd[1], 1);
close(fd[1]);
execl("./child", NULL);
}
return 0;
}
child.c
int main(int argc, char **argv) {
char line[80];
fprintf(stderr, "[child] Enter message: ");
fgets(line, 80, stdin);
printf("[child] line = %s\n", line);
return 0;
}
我找到了解决方法。我的实际目标是在 parent 和 child 之间传递信息。我的错误是在 stdin
上 dup2
。通过这样做,当程序询问时我无法输入任何内容。所以我在 argv
中传递了文件描述符的值,我的问题就解决了。
再次感谢您的帮助!