我完全不清楚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
实例阻塞。
如果您查看源代码,您会看到call
调用了Popen(...).wait()
,这就是为什么它是阻塞的原因。
check_call
调用call
,这也是为什么它被阻塞的原因。
严格来说,shell=True
与阻塞问题无关。但是,shell=True
会导致Python执行一个外壳并在外壳中运行命令。如果您使用阻塞调用,则该调用将在外壳完成时返回。由于外壳可能会生成子进程来运行命令,因此外壳可能在生成的子进程之前完成。例如:
import subprocess
import time
proc = subprocess.Popen('ls -lRa /', shell=True)
time.sleep(3)
proc.terminate()
proc.wait()
这里会生成两个进程:Popen生成一个运行shell的子进程,而shell又生成一个运行ls
的子进程。proc.terminate()
杀死了shell,但是运行ls
的子进程仍在运行(即使Python脚本已经结束,仍会有大量输出。准备好用pkill ls
来杀死ls
)。
shell=True
可能会成为安全隐患。因此,最好尽可能使用shell=False
。使用shell=False
,在列表中提供命令及其参数:proc = subprocess.Popen(['/run_python.py', '-n', '10'], shell=False)
。 - unutbuPopen
始终是非阻塞的。它调用 wait
或 communicate
会阻塞。 - unutbusubprocess.call([cmd,params,&])
有什么问题?即添加标准的 &
? - Charlie Parkershell=True
并希望它阻塞执行,直到 shell 内部进程结束,我该怎么做? - Yuval Zilber
subprocess.call([cmd,params,&])
吗? - Charlie Parker