簡體   English   中英

Python 子進程調用 output 超時

[英]Python subprocess call with output and timeout

總結:我想從 Python(3.6 版)啟動一個外部進程,非阻塞地輪詢結果,並在超時后終止。

詳細信息:有一個帶有 2 個“壞習慣”的外部進程:

  1. 它在未定義的時間后打印出相關結果。
  2. 它打印出結果后不會停止。

示例:也許以下簡單應用程序大部分類似於要調用的實際程序( mytest.py ;源代碼不可用):

import random
import time

print('begin')
time.sleep(10*random.random())
print('result=5')
while True: pass

這就是我試圖稱呼它的方式:

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()

我想在評論中實現邏輯。

分析

以下是不合適的:

  • 使用myprocess.communicate() ,因為它等待終止,並且子進程不會終止。
  • 殺死進程然后調用myprocess.communicate() ,因為我們不知道結果何時打印出來
  • 使用process.stdout.readline()因為這是一個 blocikg 語句,所以它會等到打印出一些東西。 但這里最后不打印任何東西。

io.BufferedReader myprocess.stdout 所以實際上的問題是:有沒有辦法檢查io.BufferedReader是否打印了某些內容,如果是,請閱讀它,否則不要等待?

我想我得到了您需要的確切 package。 認識一下command_runner ,它是一個子進程包裝器並允許:

  • 實時標准輸出/標准錯誤 output
  • 超時與執行無關
  • 進程樹包括在超時情況下殺死的子進程
  • stdout / stderr 重定向到隊列、文件或回調函數

使用pip install command_runner

用法:

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

如果達到超時,您將得到 exit_code -254,但仍然會得到 output 填充您的子進程寫入 stdout/stderr 的任何內容。

免責聲明:我是command_runner的作者

可以在 github 頁面上看到使用隊列的其他非阻塞示例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM