Python3子流程模块-超时后返回控制台输出



下面的代码启动了一个可执行文件,并在它完成执行后等待来自shell的响应。我的超时设置为60秒。如果可执行文件在60秒内完成其工作,那么变量streamdata是一个字符串,如果您以交互方式运行可执行文件,它将打印到控制台屏幕上。

然而,如果达到超时截止,streamdata的值似乎只是一个空白的二进制字符串。我该如何修改,以便在超时杀死.exe后仍然获得STDOUT?

startupinfo = None
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW

process = subprocess.Popen([<parameters>], stdout=subprocess.PIPE, startupinfo=startupinfo)
process2 = process.pid
streamdata = process.communicate(timeout=60)[0]
streamdata2 = streamdata.decode(errors='replace')
rc = process.returncode

让子进程将stdout重定向到一个文件(或其他文件(,然后读取它。例如:

import subprocess
import os
program_path="E:/Project2.exe"
file_path="E:/1.txt"
if os.path.exists(file_path):
os.remove(file_path)
startupinfo = None
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
with open(file_path,'w') as f:
process = subprocess.Popen([program_path],stdout=f, startupinfo = startupinfo)
process2 = process.pid
try:
streamdata = process.communicate(timeout=2)[0]
except Exception:
print("Time Out!")
with open(file_path, 'r') as f:
print(f.readlines())
process.kill()

输出:

Time Out!
['1n', '1n', '1n', '1n', '1n', '1n', '1n', '1n', '1n', '1n', '1n', '1n', '1n', '1n', '1n', '1n', '1n', '1n', '1n', '1n']

如果您想获得尽可能多的输出,请在子流程中更频繁地刷新stdout

如果您只需要在控制台中看到输出:

startupinfo = None
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW

process = subprocess.Popen([<parameters>],startupinfo=startupinfo)#<-here is the difference
process2 = process.pid
streamdata = process.communicate(timeout=60)[0]
streamdata2 = streamdata.decode(errors='replace')
rc = process.returncode

Op的回答不起作用。然而,经过一个下午的闲逛,我终于有了下面的工作。在SO上找不到任何可比的答案,但我的解决方案几乎完全基于子流程文档中给出的示例,所以学到的教训是,不要总是依赖这里,在发布之前查阅文档!

try:

startupinfo = None
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW

process = subprocess.Popen([<parameters>], stdout=subprocess.PIPE, stderr=subprocess.PIPE, startupinfo=startupinfo)
process2 = process.pid
outs, errs = process.communicate(timeout=5)
print(outs)
except subprocess.TimeoutExpired:
process.kill()
outs, errs = process.communicate(timeout=6)
print(outs)

最新更新