进程终止后Python通信被阻止

2024-09-29 23:17:04 发布

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

我正在运行一个执行Bash子进程的Python脚本。如果Bash子进程超时,那么Python脚本将打印Bash子进程的stdout。但是,如果使用“sudo”关键字执行Bash子进程,那么在超时后读取stddout会阻塞Python,那么Python脚本将按预期工作

Bash脚本(名为test Bash.sh)如下所示:

#!/bin/sh
while :
do
        echo "Press [CTRL+C] to stop.."
        sleep 1
done

Python脚本如下所示:

import subprocess
proc = subprocess.Popen("sudo ./test-bash.sh", shell=True, stdout=subprocess.PIPE)
try:
    outs, errs = proc.communicate(timeout=3)
except subprocess.TimeoutExpired:
    proc.kill()
    print("Succesfully killed")
    outs, errs = proc.communicate()
    print("Stdout: {}".format(outs))

除非我们从以下位置删除“sudo”,否则不会调用最后一次打印,在Communication()上被阻止:

proc = subprocess.Popen("sudo ./test-bash.sh", shell=True, stdout=subprocess.PIPE)

阻止Communication()的原因是什么?如果必须使用“sudo”运行Bash子进程,如何取消阻止并读取stddout()


Tags: test脚本bashtrue进程shstdoutsudo
1条回答
网友
1楼 · 发布于 2024-09-29 23:17:04

即使没有sudo,只要shell=True,问题也可以重现。这就像约翰·博林格在上面解释的,所以我不会让我们背诵了。幸运的是Popen提供了一种处理此类多级子流程的方法—它允许启动一个新会话,并由此创建一个流程组,通过该流程组可以终止所有子流程

# add start_new_session=True argument
proc = subprocess.Popen(…, stdout=subprocess.PIPE, start_new_session=True)
…
# replace proc.kill() by
    import os
    import signal
    os.killpg(proc.pid, signal.SIGTERM)

相关问题 更多 >

    热门问题