2017-04-16 47 views
2

我想實現一個python代碼,我需要運行一個外部可執行文件。經過一番研究,我發現subprocess模塊並嘗試過。然而,當我運行代碼,子進程退出並返回一個CompletedProcess對象,這是不行的我,因爲我有工作的.exe文件實際上是一個連續節目裏需要輸入,直到它被關閉產生輸出。 (我的程序將發送它的輸入並接收輸出。)使用Python運行連續的.exe文件

所以這段代碼失敗了。

import subprocess 

proc = subprocess.run("some.exe", stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
print(proc) # To see what it is. 

它捕捉標準輸出中的程序,然後退出,而不是期待新的輸入。

我也有在這裏的術語問題,這個可執行文件我現在用的就是能夠運行,同時仍然能夠收到新的命令的命令,這是所謂的異步非阻塞

我的問題,什麼是處理這個正確的方式?在接近這個的地方有很多問題,但我不能確定哪些人正在回答我的問題或以現代的方式回答問題(有很多老問題)。

這樣看來subprocess模塊經歷與Python 3.6.1一些變化https://docs.python.org/3/library/subprocess.html

因此,這將是最好的,如果你能提供的最新方式的解決方案,或者至少提到新的方式,以及它如何運作。

我的工作在Windows 10,Python的3.6.1

EDIT1:我所遇到subprocess.Popen,這可能是我所需要的,但我還沒有發現它是如何正確使用。

EDIT2:模塊pexpect似乎是專爲這些類型的問題,但我如果用這將讓我的時間更容易我不知道。任何建議感激。

+0

可以將這些「輸入」簡單地寫入子流程調用的命令嗎? – JacobIRR

+0

@JacobIRR,是的,原諒我不提,這是一個控制檯應用程序,並直接從stdin接收輸入。我可以直接運行它並測試輸入,我需要我的Python應用程序來代替我。 – Rockybilly

+0

但輸入不是預先確定的,當我在開始時調用程序時,我無法給出所有輸入。 – Rockybilly

回答

1

從文檔:

subprocess.run()

運行由ARGS中描述的命令。等待命令完成,然後返回一個CompletedProcess實例。

因爲你的子進程並不在最初稱這是結束了,您不能使用run但需要使用Popen代替。

你可以使用這樣的事情:

import subprocess 
p = subprocess.Popen(exe_path, 
        stdin=subprocess.PIPE, 
        stdout=subprocess.PIPE, 
        stderr=subprocess.STDOUT) 
while p.poll() is None: 
    p.stdin.write(some_command) 
    p.stdin.flush() 
    out = p.stdout.readline() 

但請注意,如documentation描述,這可能導致死鎖:

警告使用通信(),而不是.stdin .write,。stdout.read或.stderr.read,以避免由於任何其他OS管道緩衝區填滿和阻塞子進程而導致的死鎖。

不幸的是,您不能使用communicate,因爲這會要求您使用所有輸入調用該過程。我會嘗試使用上面的版本,看看緩衝區是否真的在您的應用程序中造成問題。

+0

感謝您的回答,在您發佈答案之前,我也遇到了這個問題,似乎是解決我的問題的唯一方法。我只需要在某些功能中包裝這些。不過,如果能夠避免這種僵局,我將不勝感激。 – Rockybilly

+0

請參閱[這裏](http://stackoverflow.com/questions/2381751/can-someone-explain-pipe-buffer-deadlock)解釋死鎖問題。提出的解決方案[here](http://stackoverflow.com/questions/375427/non-blocking-read-on-a-subprocess-pipe-in​​-python)可能有助於避免死鎖,方法是使用單獨的線程讀取數據防止填充的緩衝區。 – Felix