当前位置 : 主页 > 编程语言 > python >

Python子进程.check_call vs .check_output

来源:互联网 收集:自由互联 发布时间:2021-06-25
我的 python脚本( python 3.4.3)通过子进程调用bash脚本: import subprocess as spres = sp.check_output("bashscript", shell=True) bashscript包含以下行: ssh -MNf somehost 这将打开与某个远程主机的共享主连接,以
我的 python脚本( python 3.4.3)通过子进程调用bash脚本:

import subprocess as sp
res = sp.check_output("bashscript", shell=True)

bashscript包含以下行:

ssh -MNf somehost

这将打开与某个远程主机的共享主连接,以允许一些后续操作.

执行python脚本时,它会提示输入ssh行的密码,但是在输入密码后它会阻塞,并且永远不会返回.当我按ctrl-C终止脚本时,我看到连接已正确建立(因此ssh行已成功执行).

使用check_call而不是check_output时,我没有此阻塞问题,但check_call不检索stdout.我想了解究竟是什么导致了check_output的阻塞行为,可能与ssh -MNf的一些微妙之处有关.

只要/ bin / sh进程退出而不等待后代进程,check_call()就会返回.

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
 进程继承stdout管道):

start = time.time()
subprocess.check_output(cmd, shell=True)
assert (time.time() - start) > 2

然后它等待,直到继承管道的后台python进程退出.

check_output()调用Popen().communic()来获取输出. .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

孙子的输出被重定向到/ dev / null,即它不继承父管道,因此check_output()可以在不等待的情况下退出.

注意:&最后,将孙子python进程放入后台.它不适用于Windows默认情况下shell = True启动cmd.exe的Windows.

网友评论