我试图在提高超时的异常时尝试获得子过程输出(在Windows上(。有什么想法吗?
try:
proc = subprocess.run(cmd,timeout=3)
except subprocess.TimeoutExpired:
print(???)
您需要使用popen and subprocess.pipe。才能在超时到期时捕获进程。特别是popen.communate是您所需要的。这是一个示例
proc = subprocess.Popen(["ping", "192.168.1.1"],
stdout=subprocess.PIPE)
try:
output, error = proc.communicate(timeout=2)
except subprocess.TimeoutExpired:
proc.kill()
output, error = proc.communicate()
print(output)
print(error)
这将打印输出的过程,直到超时到期。
如果您出于任何原因无法使用 timeout
(一个太旧的python版本(,则是我的解决方案,它可以与任何python版本一起使用:
- 创建首先等待的线程,然后杀死
subprocess
对象 - 在主线程中,在循环中读取线条。
我使用的是Python子过程,使用-u
(无封闭(选项运行:
transmitter.py :(每1/10秒打印" Hello xx"的测试程序(
import time
i=0
while True:
print("hello {}".format(i))
i += 1
time.sleep(0.1)
程序本身(超时设置为1.5秒(:
import subprocess,threading,time
def timeout(p,timeout):
time.sleep(timeout)
p.kill()
p = subprocess.Popen(["python","-u","transmitter.py"],stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
t = threading.Thread(target=timeout,args=(p,1.5))
t.start()
output = []
for line in p.stdout:
output.append(line.decode())
t.join()
print("".join(output))
最后,超时后,程序打印:
hello 0
hello 1
hello 2
hello 3
hello 4
hello 5
hello 6
hello 7
hello 8
hello 9
hello 10
hello 11
hello 12
hello 13
hello 14
这是捕获多过程的Stdout的方式。
import app
import sys
import io
from multiprocessing import Process
def run_app(some_param):
sys.stdout = io.TextIOWrapper(open(sys.stdout.fileno(), 'wb', 0), write_through=True)
app.run()
app_process = Process(target=run_app, args=('some_param',))
app_process.start()
# Use app_process.termninate() for python <= 3.7.
app_process.kill()