抛出 subprocess.TimeoutExpired 后杀死 Python 子进程中的子进程

2024-06-11 23:47:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我在Python中调用一个shell脚本fom,它产生多个子进程。如果两分钟后我不想结束它的进程。在

有什么办法我能做到吗子流程.运行还是我得回去用波本?由于run是阻塞的,我不能保存pid到某个地方,以便在一个额外的命令中杀死孩子。一个简短的代码示例:

try:
    subprocess.run(["my_shell_script"], stderr=subprocess.STDOUT, timeout=120)
except subprocess.TimeoutExpired:                                                                      
    print("Timeout during execution")

Tags: run代码命令脚本示例进程地方孩子
2条回答

这个问题以bug的形式报告给Python开发人员。当stderr或stdout被重定向时,似乎会发生这种情况。 下面是@Tanu代码的更正确版本。在

import subprocess as sp

try:
    proc = sp.Popen(['ls', '-l'], stdout=sp.PIPE, stderr=sp.PIPE)
    outs, errs = proc.communicate(timeout=120)
except sp.TimeoutExpired:
    proc.terminate()

Popen不接受timeout作为参数。它必须传递给communicate。 在posixoss上,terminatekill更温和,因为它降低了创建僵尸进程的风险。在

引用文件:

subprocess.run - This does not capture stdout or stderr by default. To do so, pass PIPE for the stdout and/or stderr arguments.

如果不想使用Popen(),则不必使用。模块中的其他函数,如.call(),.Popen()。在

有三个“文件”流:stdin用于输入,stdout和stderr用于输出。应用程序决定在哪里写什么;通常将错误和诊断信息写入stderr,其余信息写入stdout。要捕获这些输出的输出,请指定子流程.管道参数,以便将“流”重定向到程序中。在

要在超时后终止子进程,请执行以下操作:

import os
import signal
import subprocess

try:
    proc = subprocess.Popen(["ls", "-l"], stdout=PIPE, stderr=PIPE, timeout=120)
except subprocess.TimeoutExpired:
    os.kill(proc.pid, signal.SIGTERM)

相关问题 更多 >