2012-02-22 60 views
1

我在使用subprocess.communicate()读取/写入子进程中的stdin/stdout时遇到问题。subprocess.communicate()发送垃圾来处理?

这是孩子的过程(在C)

#include <stdio.h> 

int main() 
{ 
    char buf[128]; 
    printf("test\n"); 
    gets(buf); 
    printf("%s", buf); 
    return 0; 
} 

这是在Python程序调用的子程序

import subprocess 

proc = subprocess.Popen('./test', stdin=subprocess.PIPE, stdout=subprocess.PIPE) 

stdin, stderr = proc.communicate() 
print stdin 
proc.communicate(stdin) 
stdin, stderr = proc.communicate() 
print stdin 

print stdin 

我希望它可以打印

test 
input was test: 

但是,似乎proc.communicate()会为gets()导致EOF,导致子应用程序终止。无论如何,我可以在不发送EOF的情况下与子应用程序进行通信? IE我想读到应用程序,然后写信给它。

+0

我接受了下面的答案,因为找到我的问题的解决方案非常重要。我还想补充一点,我需要一个'fflush(stdout);'作为输入被缓冲,这是导致问题。 – endeavormac 2012-02-22 20:38:49

回答

1

从文档Popen.communicate()

将数据发送至标准输入。从stdout和stderr中读取数据,直到达到文件结尾。等待进程终止。

这意味着您只能为子流程调用communicate()一次。获取实时输出可能有点棘手,但在您的示例中,应该不会太困难,因为您只是试图读取一行。下面应该工作:

import subprocess 

proc = subprocess.Popen('./test', stdin=subprocess.PIPE, stdout=subprocess.PIPE) 

outdata = proc.stdout.readline() 
print outdata 
outdata, errdata = proc.communicate('output was ' + outdata) 
print outdata 

注意,我改名一些你的变量,因为从你的子进程的输出是不是真的标准输入你的Python程序。

+0

+1。你也可能决定不使用通信()。有关示例,请参阅http://stackoverflow.com/questions/9322796/keep-a-subprocess-alive-and-keep-giving-it-commands-python/9327923#9327923 – user9876 2012-02-22 19:50:30