[英]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.