将subprocess的stdin和stdoutredirect到pipe道


编辑:解决scheme是

int c1=dup2(pipes[0][1],STDOUT_FILENO); int c2=dup2(pipes[1][0],STDIN_FILENO); setvbuf(stdout,NULL,_IONBF,0); 

SETVBUF将stdout设置为非缓冲。 即使我正在打印换行符,如果目标不是一个实际的屏幕,我想,它变得缓冲。



编辑:当我把fflush(标准输出)后LINE 1和fflush(fout) LINE 4后,它按预期工作。 但是,如果没有第一行之后的fflush(stdout) ,它就不能工作。问题是我不能将fflush放到我计划运行的程序中。


我正在尝试从我的过程开始另一个程序。 我没有访问它的代码,但我知道它使用标准input和标准输出用户交互。 我试图通过创build2个pipe道来启动该程序,将subprocess的stdin / stdout分叉并redirect到适当的pipe道末端。 要点是,父应该能够通过文件描述符与孩子通信,而其标准input/标准输出应该是完整的。 POPEN系统调用只打开单向pipe道。 下面的代码几乎可以工作。

有4行标记为LINE 1..4。

LINE 1是发送到pipe道的subprocess,LINE 2是从pipe道接收的subprocess,LINE 3是向pipe道发送的父进程,LINE 4是从pipe道接收的父进程,

这只是一个玩具的例子,以确保事情的工作。 问题是,所有4行LINE1..4都是未注释的输出,我看到在terminal上

 PARENT1: -1 FD: 1 0 4 5 0 1 DEBUG1: 0 DEBUG2: 0 

而如果LINE 1和LINE 3没有注释,我只能看到连续的数据stream。 如果只有LINE 2和LINE 4未注释,则会发生同样的情况。 但是,我想要一个完整的双向通信。 同时添加注释的SLEEP不会改变行为。

这里可能是什么问题。 我想知道为什么没有双向POPEN。

 int pid; int pipes[2][2]; pipe(pipes[0]); pipe(pipes[1]); pid=fork(); if(pid==0) { //usleep(1000000); close(pipes[0][0]); close(pipes[1][1]); int c1=dup2(pipes[0][1],STDOUT_FILENO); int c2=dup2(pipes[1][0],STDIN_FILENO); //int c2=dup2(STDIN_FILENO,pipes[1][0]); fprintf(stderr,"FD: %d %d %d %d %d %d\n",c1,c2,pipes[0][1],pipes[1][0],STDIN_FILENO,STDOUT_FILENO); //FILE*fout=fdopen(pipes[0][1],"w"); //FILE*fin =fdopen(pipes[1][0],"r"); while(1) { static int c1=0; fprintf(stderr,"DEBUG1: %d\n",c1); printf("%d\n",c1); // LINE 1 fprintf(stderr,"DEBUG2: %d\n",c1); scanf("%d",&c1); // LINE 2 fprintf(stderr,"DEBUG3: %d\n",c1); c1++; } //fclose(fout); //fclose(fin); return 0; } close(pipes[0][1]); close(pipes[1][0]); char buffer[100]; FILE*fin=fdopen(pipes[0][0],"r"); FILE*fout=fdopen(pipes[1][1],"w"); while(1) { int c1=-1; printf("PARENT1: %d\n",c1); fscanf(fin,"%d",&c1); // LINE 3 printf("Recv: %d\n",c1); fprintf(fout,"%d\n",c1+1); // LINE 4 printf("PARENT3: %d\n",c1+1); } fclose(fin); fclose(fout); 

你的代码很长,所以我不确定我已经理解了一切,但为什么你不使用select ? 你想在一个三角过程中重定向孩子的输出或在你的父过程中使用它?

以下例子是在儿童过程中使用猫。

 #include <unistd.h> #include <stdlib.h> int main() { pid_t pid; int p[2]; pipe(p); pid = fork(); if (pid == 0) { dup2(p[1], 1); // redirect the output (STDOUT to the pipe) close(p[0]); execlp("cat", "cat", NULL); exit(EXIT_FAILURE); } else { close(p[1]); fd_set rfds; char buffer[10] = {0}; while (1) { FD_ZERO(&rfds); FD_SET(p[0], &rfds); select(p[0] + 1, &rfds, NULL, NULL, NULL); //wait for changes on p[0] if(FD_ISSET(p[0], &rfds)) { int ret = 0; while ((ret = read(p[0], buffer, 10)) > 0) //read on the pipe { write(1, buffer, ret); //display the result memset(buffer, 0, 10); } } } } }