[英]python subprocess - detach a process
我有一個 python 腳本af_audit_run.py
,它通過subprocess
調用另一個 python 腳本request_audit.py
。
第二個腳本request_audit.py
在后台調用另一個子進程並返回一個請求 ID。
問題是第一個腳本af_audit_run.py
應該在第二個腳本返回請求 ID 后立即退出,正在等待整個后台進程完成。 有什么方法可以在返回請求 ID 后強制第一個腳本退出?
af_audit_run.py
-- 使用communicate
方法等待結果:
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
result, error = p.communicate()
print(result.decode('utf-8'))
print(error.decode('utf-8'))
request_audit.py
-- 不等待,只是分離一個子進程(第 3 個 python 腳本)並返回請求 ID:
subprocess.Popen(cmd, shell=True, stdout=None, stderr=None, close_fds=True)
print(request_id)
環境:Linux
您需要確保標准 output 和第三個進程的標准錯誤被定向到 pipe 以外的其他地方, af_audit_run.py
正在從中讀取 Z78E6221F6393D1356DZZCE.CE.
現有代碼的問題在於,通過使用stdout=None, stderr=None
,您正在請求默認操作(就好像您根本沒有使用這些關鍵字一樣)。 這是寫入與父進程相同的 output 流,在本例中為request_audit.py
,使用子進程分叉時繼承的文件描述符。 這意味着頂級af_audit_run.py
將等待 output 因為它沒有看到 output ZF7B44CFAFD5C52223D5498196C8A2E7B 上的文件結尾,直到第三個過程完成。
這可以在lsof
的output中看到——在下面的例子中,第三個進程是命令/bin/sleep 600
(見最后的測試代碼)。
這是第三個進程的lsof
output 的一部分:
sleep 3057 myuser 0u CHR 136,20 0t0 23 /dev/pts/20
sleep 3057 myuser 1w FIFO 0,13 0t0 9441062 pipe
sleep 3057 myuser 2w FIFO 0,13 0t0 9441063 pipe
這是頂級af_audit_run.py
的lsof
output 的一部分:
python3 3053 myuser 0u CHR 136,20 0t0 23 /dev/pts/20
python3 3053 myuser 1u CHR 136,20 0t0 23 /dev/pts/20
python3 3053 myuser 2u CHR 136,20 0t0 23 /dev/pts/20
python3 3053 myuser 3r FIFO 0,13 0t0 9441062 pipe
python3 3053 myuser 5r FIFO 0,13 0t0 9441063 pipe
如您所見,此示例中的sleep
進程 (pid 3057) 將其 stdout (fd 1) 和 stderr (fd 2) 流連接到頂級進程 (pid 3053) 正在讀取的管道的寫入端 - - 注意倒數第二列中的 pipe 數字——即使它不是該進程的直接父進程。
您正在指定close_fds=True
,但這記錄如下:
“如果close_fds為真,除了0、1、2之外的所有文件描述符都會在子進程執行前關閉。” (強調我的)
所以它對標准輸入、標准輸出或標准錯誤流沒有任何影響,盡管任何其他打開的文件描述符都會在子進程中關閉。
如果您使用 stdout stdout=None, stderr=None
而不是 stdout=subprocess.DEVNULL stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
subprocess.DEVNULL ,那么這會將這些流顯式定向到 null 設備(Linux 上的/dev/null
),然后是af_audit_run.py
不必等待。
在這種情況下,來自lsof
的一些 output :
sleep 3318 myuser 0u CHR 136,20 0t0 23 /dev/pts/20
sleep 3318 myuser 1u CHR 1,3 0t0 6 /dev/null
sleep 3318 myuser 2u CHR 1,3 0t0 6 /dev/null
也可以使用stdin=subprocess.DEVNULL
,這樣如果進程嘗試讀取,那么它將看到文件結尾。 在這個例子中我沒有這樣做,它的輸入仍然連接到終端設備,雖然這並不影響af_audit_run.py
是否等待它。
af_audit_run.py
import subprocess
cmd = "python3 request_audit.py"
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
result, error = p.communicate()
print(result.decode('utf-8'))
print(error.decode('utf-8'))
request_audit.py
import subprocess
cmd = "/bin/sleep 600"
subprocess.Popen(cmd, shell=True,
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
print(5)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.