Python的子.check_call VS .check_output [英] Python subprocess .check_call vs .check_output

查看:381
本文介绍了Python的子.check_call VS .check_output的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的python脚本(蟒蛇3.4.3),通过子调用一个bash脚本:

My python script (python 3.4.3) calls a bash script via subprocess:

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

bashscript 包含以下行:

ssh -MNf somehost

这将打开一个共享的主站连接到一些远程主机允许一些后续操作。

which opens a shared master connection to some remote host to allow some subsequent operations.

在执行python脚本,它会提示密码为 SSH 行,但随后块密码后,输入并永远不会返回。当我Ctrl-C来终止脚本,我看到该连接是正确建立(所以成功执行 SSH 线)。

When executing the python script, it will prompt for password for the ssh line but then it blocks after the password is entered and never returns. When I ctrl-C to terminate the script, I see that the connection was properly established (so ssh line was successfully executed).

使用时,我没有这个阻塞问题 check_call 而不是 check_output ,但 check_call 不检索标准输出。我想知道究竟是什么原因造成的阻塞行为 check_output ,可能与一些微妙与 SSH -MNf

I don't have this blocking problem when using check_call instead of check_output, but check_call does not retrieve stdout. I'd like to understand what exactly is causing the blocking behavior for check_output, probably related to some subtlety with ssh -MNf.

推荐答案

check_call()尽快返回为 / bin / sh的退出过程无需等待后续进程。

check_call() returns as soon as /bin/sh process exits without waiting for descendant processes.

check_output()等待,直到所有的输出被读取。如果 SSH 继承管那么 check_output()将等待,直到它退出(直到它关闭其继承管端)。

check_output() waits until all output is read. If ssh inherits the pipe then check_output() will wait until it exits (until it closes its inherited pipe ends).

check_call() code例如:

#!/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()立即返回,而无需等待孙子背景蟒蛇的过程。

The output is not read; check_call() returns immediately without waiting for the grandchild background python process.

check_call()就是 POPEN()。等待() POPEN()启动外部进程,不等待它退出立即返回。 .wait()收集该进程的退出状态 - 它不会等待其他(孙子)工艺

check_call() is just Popen().wait(). Popen() starts the external process and returns immediately without waiting for it to exit. .wait() collects the exit status for the process -- it doesn't wait for other (grandchildren) processes.

如果输出读取(它会被重定向和孙子蟒蛇
 进程继承stdout管道):

If the output is read (it is redirected and the grandchild python process inherits the stdout pipe):

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

然后等待直到继承了管道出口后台蟒蛇进程。

then it waits until the background python process that inherited the pipe exits.

check_output()通话 POPEN()。通信(),得到的输出。 .communicate()通话 .wait()内部即 check_output()还有待shell退出和 check_output()等待EOF。

check_output() calls Popen().communicate(), to get the output. .communicate() calls .wait() internally i.e., check_output() also waits for the shell to exit and check_output() waits for EOF.

如果孙子不继承管那么 check_output()不等待它:

If the grandchild doesn't inherit the pipe then check_output() doesn't wait for it:

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()可能会退出,而无需等待吧。

Grandchild's output is redirected to /dev/null i.e., it doesn't inherit the parent's pipe and therefore check_output() may exit without waiting for it.

请注意:&安培; 在这使孙蟒蛇过程分为后台结束。其中,壳= TRUE 启动的cmd.exe 默认情况下,它不会在Windows上运行。

Note: & at the end which puts the grandchild python process into background. It won't work on Windows where shell=True starts cmd.exe by default.

这篇关于Python的子.check_call VS .check_output的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆