check_call() 在/bin/sh 进程退出后立即返回,而无需等待后代进程(假设shell=True 与您的情况一样)。
check_output() 等待直到读取所有输出。如果ssh 继承了管道,那么check_output() 将一直等到它退出(直到它关闭其继承的管道结束)。
check_call() 代码示例:
#!/usr/bin/env python
import subprocess
import sys
import time
start = time.time()
cmd = sys.executable + " -c 'import time; time.sleep(2)' &"
subprocess.check_call(cmd, shell=True)
assert (time.time() - start) < 1
输出未被读取; check_call() 立即返回,无需等待孙子后台python进程。
check_call() 只是Popen().wait()。 Popen() 启动外部进程并立即返回,无需等待它退出。 .wait() 收集进程的退出状态——它不等待其他(孙)进程。
如果输出被读取(它被重定向并且孙子python
进程继承标准输出管道):
start = time.time()
subprocess.check_output(cmd, shell=True)
assert (time.time() - start) > 2
然后它一直等到继承管道的后台python进程退出。
check_output() 调用Popen().communicate(),以获取输出。 .communicate() 在内部调用 .wait(),即 check_output() 也等待 shell 退出,check_output() 等待 EOF。
如果孙子没有继承管道,那么check_output() 不会等待它:
start = time.time()
cmd = sys.executable + " -c 'import time; time.sleep(2)' >/dev/null &"
subprocess.check_output(cmd, shell=True)
assert (time.time() - start) < 1
Grandchild 的输出被重定向到 /dev/null,即它不会继承父管道,因此 check_output() 可能会在不等待的情况下退出。
注意:& 最后将孙子 python 进程置于后台。它不适用于默认情况下 shell=True 以 cmd.exe 开头的 Windows。