簡體   English   中英

Python 進程終止后通信被阻止

[英]Python communicate is blocked after process kill

我正在運行執行 Bash 子進程的 Python 腳本。 如果 Bash 子進程超時,則 Python 腳本預計會打印 Bash 子進程的標准輸出。 Python 腳本按預期工作,但是,如果使用“sudo”關鍵字執行 Bash 子進程,則在超時后讀取 stddout 會阻塞 ZA7F5F35426B927411FC9231B563821。

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”:

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

阻塞通信()的原因是什么? 如果我必須使用“sudo”運行 Bash 子進程,我該如何解鎖它並讀取 stddout()?

即使沒有sudo也可以重現問題,前提是shell=True 就像上面解釋的約翰·布林格一樣,所以我將省去我們的背誦。 幸運的是, Popen提供了一種處理這種多級子進程的方法——它允許啟動一個新的 session 並創建一個進程組,通過該進程組可以殺死所有子進程。

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

暫無
暫無

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

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