2012-03-12 56 views
6

我正在嘗試使用subprocess模塊與使用Python的命令行聊天機器人進行通信。 (http://howie.sourceforge.net/使用編譯的win32二進制文件,我有我的理由!)Python子進程交互,爲什麼我的進程與Popen.communicate協同工作,但不是Popen.stdout.read()?

這工作:

proc = Popen('Howie/howie.exe', stdout=PIPE,stderr=STDOUT,stdin=PIPE) 
output = proc.communicate() 

Popen.communicate等待進程結束(並將其發送EOF ?),我希望能夠與它互動。這樣做的明顯的解決方案是讀stdout /寫stdin像這樣:

這不起作用:

proc = Popen('Howie/howie.exe', stdout=PIPE,stderr=STDOUT,stdin=PIPE) 
while True: print proc.stdout.readline() 

(請注意,我實際上使用基於http://code.activestate.com/recipes/440554/更復雜的代碼,但問題是相同)

問題是,第二種方法完美地用於與cmd通信,但是當我運行chatbot時,什麼也沒有。所以我的問題是,這是不同的捕獲輸出使用Popen.communicate()?

即我可以使用第二種方法來按照正常情況使用命令行,直到我運行chatbot,此時我停止接收輸出。使用第一種方法正確顯示機器人的前幾行輸出,但是我無法與之交互。

回答

9

這兩者之間的一個主要區別是communicat()在發送數據後關閉stdin。我不知道你的特定情況,但在很多情況下,這意味着如果一個進程正在等待用戶輸入的結束,他將在使用通信()時得到它,並且在代碼阻塞時不會得到它read()或readline()。

嘗試先添加Popen.stdin.close(),看看它是否會影響你的情況。

+0

爲什麼感謝你,關閉stdin讓chatbot開始完全按照'Popen.communicate'所做的那樣,儘管現在我有一個問題需要我能夠繼續和它交談...... – SudoNhim 2012-03-12 20:52:45

+0

也許你的應用程序正在閱讀行在這種情況下,您可以發送單行讓它回覆?你試圖完成的確切任務是什麼? – vmalloc 2012-03-12 20:57:49

+0

但是一旦stdin被關閉,我怎麼才能發送它呢? 我希望能夠一行一行地提交和接收 – SudoNhim 2012-03-12 21:00:26

3

如果您想要在發送EOF後與程序進行交互,而不是使用Popen.stdin.close(),則可以手動發送命令行結尾文件字符,它具有相同的效果,但會使標準輸入打開。

在Python中,這個字符的轉義序列是'\x1a'

相關問題