我完全混淆subprocess.call()
,subprocess.Popen()
,subprocess.check_call()
。阻塞和不阻塞子進程調用
哪個阻塞,哪個不是?
我的意思是說,如果我使用subprocess.Popen()
父進程是否等待子進程到return
/exit
,然後繼續執行。
shell=True
如何影響這些調用?
我完全混淆subprocess.call()
,subprocess.Popen()
,subprocess.check_call()
。阻塞和不阻塞子進程調用
哪個阻塞,哪個不是?
我的意思是說,如果我使用subprocess.Popen()
父進程是否等待子進程到return
/exit
,然後繼續執行。
shell=True
如何影響這些調用?
Popen
是非阻塞的。 call
和check_call
正在阻止。 您可以通過調用wait
或communicate
方法來製作Popen
實例塊。
如果你在the source code看,你會看到call
調用Popen(...).wait()
,這就是爲什麼它阻止。 check_call
調用call
,這也是它阻塞的原因。
嚴格來說,shell=True
正交於阻塞問題。但是,shell=True
會導致Python執行一個shell,然後在shell中運行該命令。如果您使用阻止呼叫,當shell完成時,呼叫將返回。由於shell可能會產生一個子進程來運行命令,因此shell可能會在產生的子進程之前完成。例如,
import subprocess
import time
proc = subprocess.Popen('ls -lRa /', shell=True)
time.sleep(3)
proc.terminate()
proc.wait()
這裏生成了兩個進程:Popen生成一個運行shell的子進程。殼又產生運行ls
的子進程。 proc.terminate()
殺死shell,但仍運行ls
的子進程。 (即使python腳本已經結束,也會顯示出豐富的輸出,準備好用pkill ls
來殺死ls
。)
['start_new_session = True'或其類似物](http://stackoverflow.com/a/13256908/4279)可立即終止整個進程樹。請參閱[如何終止使用shell = True啓動的python子進程](http://stackoverflow.com/q/4789837/4279) – jfs
謝謝你的回答幫助了我很多。附: 'proc = subprocess.Popen(['/ run_python.py','-n','10'],shell = True)'不同於'proc = subprocess.Popen(「run_python.py -n 10」, shell = True)'只有最後一個工作,如果命令是建立在python腳本之上的。 – dotslash
@dotslash:'shell = True'如果命令來自用戶輸入,可能是[安全隱患](https://docs.python.org/2/library/subprocess.html#using-the-subprocess-module) 。所以如果可能的話最好使用'shell = False'。用'shell = False',在列表中提供命令及其參數:'proc = subprocess.Popen(['/ run_python.py','-n','10'],shell = False)'。 – unutbu
您是否嘗試過'subprocess.call([cmd,params,&])'? –