[英]Python subprocess call with output and timeout
Summary : I want to start an external process from Python (version 3.6), poll the result nonblocking, and kill after a timeout.总结:我想从 Python(3.6 版)启动一个外部进程,非阻塞地轮询结果,并在超时后终止。
Details : there is an external process with 2 "bad habits":详细信息:有一个带有 2 个“坏习惯”的外部进程:
Example : maybe the following simple application resembles mostly the actual program to be called ( mytest.py
; source code not available):示例:也许以下简单应用程序大部分类似于要调用的实际程序( mytest.py
;源代码不可用):
import random
import time
print('begin')
time.sleep(10*random.random())
print('result=5')
while True: pass
This is how I am trying to call it:这就是我试图称呼它的方式:
import subprocess, time
myprocess = subprocess.Popen(['python', 'mytest.py'], stdout=subprocess.PIPE)
for i in range(15):
time.sleep(1)
# check if something is printed, but do not wait to be printed anything
# check if the result is there
# if the result is there, then break
myprocess.kill()
I want to implement the logic in comment.我想在评论中实现逻辑。
Analysis分析
The following are not appropriate:以下是不合适的:
myprocess.communicate()
, as it waits for termination, and the subprocess does not terminate.使用myprocess.communicate()
,因为它等待终止,并且子进程不会终止。myprocess.communicate()
, because we don't know when exactly the result is printed out杀死进程然后调用myprocess.communicate()
,因为我们不知道结果何时打印出来process.stdout.readline()
because that is a blocikg statement, so it waits until something is printed.使用process.stdout.readline()
因为这是一个 blocikg 语句,所以它会等到打印出一些东西。 But here at the end does not print anything.但这里最后不打印任何东西。 The type of the myprocess.stdout
is io.BufferedReader
. io.BufferedReader
myprocess.stdout
So the question practically is: is there a way to check if something is printed to the io.BufferedReader
, and if so, read it, but otherwise do not wait?所以实际上的问题是:有没有办法检查io.BufferedReader
是否打印了某些内容,如果是,请阅读它,否则不要等待?
I think I got the exact package you need.我想我得到了您需要的确切 package。 Meet command_runner
, which is a subprocess wrapper and allows:认识一下command_runner
,它是一个子进程包装器并允许:
Install with pip install command_runner
使用pip install command_runner
Usage:用法:
from command_runner import command_runner
def callback(stdout_output):
# Do whatever you want here with the output
print(stdout_output)
exit_code, output = command_runner("python mytest.py", timeout=300, stdout=callback, method='poller')
if exit_code == -254:
print("Oh no, we got a timeout")
print(output)
# Check for good exit_code and full stdout output here
If timeout is reached, you'll get exit_code -254 but still get to have output filled with whatever your subprocess wrote to stdout/stderr.如果达到超时,您将得到 exit_code -254,但仍然会得到 output 填充您的子进程写入 stdout/stderr 的任何内容。
Disclaimer: I'm the author of command_runner
免责声明:我是command_runner
的作者
Additional non blocking examples using queues can be seen on the github page.可以在 github 页面上看到使用队列的其他非阻塞示例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.