2011-07-08 53 views
2

我試圖運行下面的代碼作爲子Python的子模塊:父子溝通不工作

#include<stdio.h> 
int main() 
{ 
    int a; 
    printf("Hello\n"); 
    fprintf(stderr, "Hey\n"); 
    scanf("%d", &a); 
    printf("%d\n", a); 
    return 0; 
} 

該腳本正常工作:寫標準輸入,從標準輸出和標準錯誤,從讀取。

#!/usr/bin/python 

import subprocess 

p1=subprocess.Popen("/mnt/test/a.out", stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) 

p1.stdin.write('1\n') 
print p1.stdout.readline() 
print p1.stderr.readline() 
print p1.stdout.readline() 

但這個腳本無法讀取標準輸出的任何輸出和被封鎖那裏,即使C程序可以打印任何苛刻的輸入之前到標準輸出。爲什麼我無法從stdout中讀取任何內容?

#!/usr/bin/python 

import subprocess 

p1=subprocess.Popen("/mnt/test/a.out", stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) 

print p1.stdout.readline() 
p1.stdin.write('1\n') 
print p1.stderr.readline() 
print p1.stdout.readline() 

回答

0

我沒有看到類似

stdout_data, stderr_data = p1.communicate() 
在你的代碼

Popen.communicate(輸入=無)

與互動過程

:發送數據到標準輸入。從stdout和stderr中讀取數據,直到達到文件結尾。等待進程終止。可選的輸入參數應該是要發送到子進程的字符串,如果沒有數據應該發送給子進程,則爲None。

communicate()返回一個元組(stdoutdata,stderrdata)。

請注意,如果要將數據發送到進程的stdin,則需要使用stdin = PIPE創建Popen對象。同樣,要在結果元組中獲得除None以外的任何內容,您還需要輸出stdout = PIPE和/或stderr = PIPE。

注意讀取的數據會緩衝在內存中,因此如果數據量較大或無限,則不要使用此方法。

docs.python.org

我保持我的工具帶一個函數來包裝用子是這樣(修改以滿足您的需求)調用外部程序:

def __run(self, cmd): 
    """wrapper, makes it easy to call an external program. 
    return the result as a newline-separated list 
    """ 

    args = shlex.split(cmd) 
    try: 
     p = subprocess.Popen(args, stdout=subprocess.PIPE, 
          stderr=subprocess.STDOUT) 
     retdata = p.communicate()[0] 
     p.wait() 
    except OSError, e: 
     print >>sys.stderr, "Execution failed:", e 

    return (p.returncode, retdata.split('\n')) 

只需將您的命令因爲你會寫在cmd行的變量中,調用函數例如:

cmd = r'git branch -r' 
data = self.__run(cmd) 
+1

我不認爲他需要'溝通()' - 因爲「等待進程終止」。這就是爲什麼 - 我認爲 - p.wait()在代碼中是多餘的,因爲它做同樣的事情,本質上。 – phant0m

2

您需要流首先是flush。這將確保所有數據實際寫入流中。

#include<stdio.h> 
int main() 
{ 
    int a; 
    printf("Hello\n"); 
    fprintf(stderr, "Hey\n"); 
    fflush(stdout); // <-- 
    scanf("%d", &a); 
    printf("%d\n", a); 
    return 0; 
} 

默認情況下,標準錯誤無緩衝,這就是爲什麼你不需要刷新它。 標準輸出但是完全緩衝,除非它指向一個終端,那麼就行緩衝(即\n會自動觸發沖洗。

看一看here,對函數setbuf()和setvbuf用來()。