2012-02-22 54 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