【问题标题】:Python: Retain a child process after killing the parent processPython:杀死父进程后保留子进程
【发布时间】:2020-06-02 09:11:58
【问题描述】:

我正在开发一个简单的烧瓶应用程序,并且我有一个端点,可以根据请求创建一个 bash 会话。即使我杀死烧瓶,我也希望保留该过程。

该过程使用subprocess.Popen() 启动,我希望它即使在从终端执行killall python 后仍然存在。

我尝试在 Popen 上设置 preexec_fn=os.setsidpreexec_fn=setpgrp 参数,但运行 killall 仍然会杀死我在 Flask 应用程序中创建的 bash-shell。

相关代码:

def run_command(command):
        Process.proc = subprocess.Popen(
            command,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            universal_newlines=True,
            preexec_fn=os.setsid,
        )

run_command(['bash', '-c', 'for((i=0;i<1000;i++)); do echo $i; sleep 1; done; echo EOF'])

我将不胜感激任何指针。谢谢。

【问题讨论】:

  • 您可能希望引用this thread,因为默认情况下,当父进程被杀死时,子进程不会退出,但是您有stdoutstderr 被管道返回给父进程,所以当父进程被杀死,子进程,管道的另一端死了,也死了。如果去掉stdoutstderr参数,你会发现程序在调用Popen后立即退出,而bash会继续执行,并在终端回显数字。

标签: python python-3.x linux process subprocess


【解决方案1】:

您可能希望使用文档 (17.5.1) 中的 recommended 的 subprocess.run() 而不是直接使用 Popen。

# Python3.5 or above:
from subprocess import PIPE, run

def run_command(cmd:str):
    run(cmd, universal_newlines=True)

def run_piped_command(cmd:str):
    result = run(cmd, stdout=PIPE, stderr=PIPE, universal_newlines=True)
    return result.stdout, result.stderr

如果您不按照@metatoaster 的说明通过管道输出,进程将继续执行,如果您运行killall python 命令,它将输出一个很好的python: no process found 消息。

【讨论】:

  • 将 preexec_fn=os.setpgrp 作为参数添加到 run 函数就可以了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-05
  • 1970-01-01
  • 1970-01-01
  • 2010-12-08
  • 2014-06-19
  • 2018-10-14
相关资源
最近更新 更多