前 60 秒的子进程捕获输出

subprocess capture output of first 60 seconds

我有一个很长的 运行ning 进程(带日志的 k8s 作业),我希望通过 subprocess.check_output 运行。我只关心前60秒命令的输出,所以我这样做了:

out = subprocess.check_output(
    shlex.split(command),
    timeout=60,
)

但是,由于过程 运行s 的时间更长,因此以该异常结束。 raise TimeoutExpired( subprocess.TimeoutExpired: Command ... 。有没有办法在 60 秒时简单地终止命令并捕获输出。输出很重要,因为我希望在前 60 秒内对输出进行一些 post 处理。

您可以使用 bare Popen 自行替换,但这有点麻烦。基本上是从 Read streaming input from subprocess.communicate() 抄袭并添加超时;

from subprocess import Popen, PIPE
import shlex
from datetime import datetime, timedelta

deadline = datetime.now() + timedelta(seconds=60)
with Popen(
    shlex.split(command), stdout=PIPE, bufsize=1,
    text=True, check=True
) as p:
    for line in p.stdout:
        print(line, end='')
        if datetime.now() >= deadline:
           break

显然,除了 print 之外,您还可以对输出执行其他操作 - 可能会将其收集到一个列表中,以便您可以在循环后检查它。

check=True 在这里有点用处,但模仿了 check_output 的行为,如果子进程失败,它会引发异常。当然,它可以防止 command 等中的拼写错误。