![](/img/trans.png)
[英]Output of proc.communicate() does not format newlines in django python
[英]why does python.subprocess hang after proc.communicate()?
我有一個名為my_own_exe
的交互式程序。 首先,它打印出alive
,然后你輸入S\\n
然后它再次打印出alive
。 最后你輸入L\\n
。 它進行一些處理並退出。
但是,當我從以下 python 腳本調用它時,該程序似乎在打印出第一個 'alive' 后掛起。
這里有人能告訴我為什么會這樣嗎?
// 閱讀完后續(謝謝大家)后,我修改了代碼如下:
import subprocess
import time
base_command = "./AO_FelixStrategy_UnitTest --bats 31441 --chix 12467 --enxutp 31884 --turq 26372 --symbol SOGN --target_date " + '2009-Oct-16'
print base_command
proc2 = subprocess.Popen(base_command, shell=True , stdin=subprocess.PIPE,)
time.sleep(2);
print "aliv"
proc2.communicate('S\n')
print "alive"
time.sleep(6)
print "alive"
print proc2.communicate('L\n')
time.sleep(6)
該程序現在與第一個輸入 'S\\n' 運行良好,但隨后停止,而第二個 'L\\n' 有點被忽略。
誰能告訴我為什么會這樣?
與進程交互:將數據發送到標准輸入。 從 stdout 和 stderr 讀取數據,直到到達文件結尾。 等待進程終止。
因此,在communicate()
運行后,該進程已終止。
如果您想在不等待進程停止的情況下進行寫入和讀取:
永遠不要使用shell=True
- 它不必要地調用一個 shell 來調用你的程序,所以你和你的程序之間會有另一個進程。 這有很多令人不快的副作用。 默認是shell=False
所以你應該堅持下去。 將您的Popen
行更改為:
p = subprocess.Popen(["./AO_FelixStrategy_UnitTest", "--bats", "31441", "--chix", "12467", "--enxutp", "31884", "--turq", "26372", "--symbol", "SOGN", "--target_date", '2009-Oct-16'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
使用p.stdin.write
寫入進程。 使用p.stdout.read
從中讀取。
p.stdout.read
會阻塞。 如果寫入緩沖區已滿,則調用p.stdin.write
將阻塞。 所以你必須確保你有一些東西可以讀/寫 - 你可以在 unix OS 上使用select
做到這一點。 不幸的是,在 Windows 上,您必須求助於線程。 至少這是Popen.communicate
在內部所做的。AO_FelixStrategy_UnitTest
那么您可能會遇到其他問題:
AO_FelixStrategy_UnitTest
緩沖區。 默認情況下,標准 C PIPE 通信是緩沖的,因此在關閉輸入端之前您可能看不到任何輸出(通過執行p.stdin.close()
。除非AO_FelixStrategy_UnitTest
定期刷新輸出。 這是一些示例代碼,基於您的描述。 它可以根據AO_FelixStrategy_UnitTest
開發方式工作:
p = subprocess.Popen(["./AO_FelixStrategy_UnitTest",
"--bats", "31441", "--chix", "12467",
"--enxutp", "31884", "--turq", "26372",
"--symbol", "SOGN", "--target_date", '2009-Oct-16'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
output = p.communicate('S\nL\n')[0]
print output
communicate()
從標准輸出和標准錯誤讀取數據,直到到達文件結尾。 - 它一直等到你的程序退出。
comunicate只會運行一次,然后會關閉管道,因此如果您想向它發送多個命令,您需要在同一個字符串中一個接一個地發送。
這是經過一些調查后對我有用的示例,嘗試了線程、subprocess32、stdin.write、stdout.read 等。此信息不在用於通信的官方 python 參考信息中: https ://docs.python.org/ 2/library/subprocess.html
我發現這一點的唯一地方是在這里: Python subprocess communication kills my process
這是代碼,它很簡單,沒有線程,沒有 subprocess32,適用於 linux 和 windows。 是的,您必須知道向另一個進程發送命令的次數,但通常您確實知道這一點。 在此之上,您可以添加線程、cwd、shell=True 或您可能想要的任何其他內容,但這是最簡單的情況:
def do_commands(self, cmd, parms):
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE )
# wait for the process to terminate
out, err = process.communicate(cmd_parms)
errcode = process.returncode
return errcode, out, err
因此,例如,如果您想向被調用的應用程序發送多個回車符 (\\n) 以及中間的 a 參數(交互式地提醒您),您可以這樣稱呼它:
cmd_parms = "\n\n\n\n\nparm\n\n"
errcode, out, err = do_commands(command, cmd_parms)
希望能幫助到你。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.