我正在尝试读取子进程的 STDOUT。
这是 fork 函数(是的,c++)。
bool ForkAvecBus::start() {
child_pid = fork();
if(child_pid == -1)
return true;
if(child_pid == 0) {
/* Child process closes up input side of pipe */
close(child_stdin[WRITE]);
dup2 (child_stdin[READ], STDIN_FILENO);
close(child_stdout[READ]);
dup2 (child_stdout[WRITE], STDOUT_FILENO);
close(child_stdout[WRITE]);
execl("/bin/sh", "/bin/sh", "-c", ExecName.c_str(), NULL);
exit(0);
} else {
/* Parent process closes up output side of pipe */
close(child_stdin[READ]);
close(child_stdout[WRITE]);
signal(SIGTERM,exit_on_parent_quit);
}
}
这是子进程中的(简单)测试:
int main() {
fprintf(stdout, "fromFprintf\n", 12);
puts("auieauie");
write(STDOUT_FILENO, "fromWrite", 9);
}
阅读方法如下:
void ForkAvecBus::readFromChild() {
FILE* fp = fdopen(child_stdout[READ], "r");
// Tests
int bytes_read = -1;
char readbuffer[1000];
while (1) {
//char c=getc(fp);
//std::cout << "From child: <<" << c << ">>" << std::endl;
bytes_read = read(child_stdout[READ], readbuffer, 999);
if (bytes_read <= 0)
break;
readbuffer[bytes_read] = '\0';
std::cout << "From child: <<" << readbuffer << ">>" << std::endl;
}
}
如您所见,我也尝试了 getc() 。 我得到的只是:
From child: <<fromWrite>>
为什么不重定向 fprintf(和 printf)和 puts?
最佳答案
您在此处观察到的行为可能是由于缓冲区。由于 write(STDOUT_FILENO,...)
绕过运行时缓冲区,因此它直接到达管道。其他两个在运行时内缓冲。
puts
、fprintf(stdout,...)
和write(STDOUT_FILENO,...)
的区别在这解释了邮寄:The difference between stdout and STDOUT_FILENO in LINUX C
只需在您的子程序结束时调用 fflush
。
检验理论:
#include<cstdio>
#include<unistd.h>
int main() {
fprintf(stdout, "fromFprintf\n", 12);
puts("auieauie");
write(STDOUT_FILENO, "fromWrite", 9);
return 0;
}
程序打印:
fromWritefromFprintf
auieauie
看到订单不是您所期望的。我的建议是不要在程序中遗漏 STDOUT_FILENO
和 stdout
。坚持使用其中之一,并记得调用 fflush
。
关于c++ - dup2 : write() redirected but not fprintf() or puts(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36821972/