如何從Python中的終端接收輸入?從Python中讀取終端
我正在使用Python與另一個生成用戶輸入輸出的程序進行交互。 我使用subprocess.Popen()來輸入到程序,但我不能將stdout設置爲subprocess.PIPE,因爲程序似乎沒有刷新過,所以一切都卡在緩衝區中。 該程序的標準輸出似乎是打印到終端,我看到輸出時,我不重定向標準輸出。但是,我需要Python來讀取和解釋現在在終端中的輸出。
對不起,如果這是一個愚蠢的問題,但我似乎無法得到這個工作。
如何從Python中的終端接收輸入?從Python中讀取終端
我正在使用Python與另一個生成用戶輸入輸出的程序進行交互。 我使用subprocess.Popen()來輸入到程序,但我不能將stdout設置爲subprocess.PIPE,因爲程序似乎沒有刷新過,所以一切都卡在緩衝區中。 該程序的標準輸出似乎是打印到終端,我看到輸出時,我不重定向標準輸出。但是,我需要Python來讀取和解釋現在在終端中的輸出。
對不起,如果這是一個愚蠢的問題,但我似乎無法得到這個工作。
您是否嘗試過將您的Popen
對象中的bufsize
設置爲0
?我不確定你是否可以強制緩衝區從接收大小緩衝,但我會嘗試。
http://docs.python.org/library/subprocess.html#using-the-subprocess-module
緩衝的子進程是一個常見的問題。這裏有四種可能的方法。
首先,最簡單的方法是,您可以從管道中一次讀取一個字節。這就是我所說的「骯髒的黑客攻擊」,它具有性能損失,但它很容易,它保證你的read()調用只會阻塞,直到第一個字節進入,而不是等待緩衝區填滿永遠不會填滿。但是,這不會強制另一個進程刷新其寫入緩衝區,所以如果這是問題,那麼這種方法無論如何不會幫助你。
其次,我認爲下一個最簡單的,考慮使用具有使用虛擬終端或pty(我認爲是「僞電傳」)設施的Twisted框架與您的子進程交談。但是,這可能會影響應用程序的設計(可能會更好,但這可能不適用於您)。 http://twistedmatrix.com/documents/current/core/howto/process.html
如果上述兩個選項都不適用於您,那麼您可以減少爲自己解決堅韌不拔的I/O併發問題。第三,嘗試使用fcntl()和O_NONBLOCK設置你的管道(所有的,在fork()之前)到非阻塞模式。然後,您可以在嘗試讀取/寫入之前使用select()來測試讀/寫的準備情況;但是您仍然需要捕獲IOError並測試EAGAIN,因爲即使在這種情況下它也可能發生。這可能取決於子進程的行爲,允許您在嘗試讀取數據之前等待數據真正顯示。
最後的手段是自己實現PTY邏輯。如果你看過termio選項,ioctl()調用等的引用,那麼這就是你所反對的。我之前沒有這樣做過,因爲它很複雜,我從來沒有真正需要。如果這是你的命運,祝你好運。
如果程序需要交互式輸入/輸出,請嘗試pexpect:http://www.noah.org/wiki/Pexpect。如果沒有,使用subprocess.PIPE並調用'myprocess.communicate()'應該可以工作。 – 2011-06-15 17:42:59