Python - subprocess - getstatusoutput

4

我是一个新手,对Python和编程都不太了解。我从Google的Python课堂上学到了如何使用外部命令:

(status, output) = commands.getstatusoutput(cmd)
if status: ## 出错时,将命令的输出写入标准错误并退出
sys.stderr.write(output)
sys.exit(1)

但我认为commands模块已经过时了。我想要获取状态和输出,以便在出错时使用sys.stderr.write()打印输出。那么,在subprocess模块中有没有等价的命令?我目前使用的是:

subprocess.call(args,shell=False)

谢谢!


try 块中使用 subprocess.check_output 将是最接近的等效方式。 - Blender
4个回答

4

Python 3 中有 subprocess.getstatusoutput() 可以使用,它的实现可以参考这里

from subprocess import check_output, CalledProcessError, STDOUT

def getstatusoutput(cmd):
    try:
        data = check_output(cmd, shell=True, universal_newlines=True, stderr=STDOUT)
        status = 0
    except CalledProcessError as ex:
        data = ex.output
        status = ex.returncode
    if data[-1:] == '\n':
        data = data[:-1]
    return status, data

两者都返回与原始commands.getstatusoutput()不同的status。请参阅 Python问题:记录和unittest subprocess.getstatusoutput()状态值


2

也有可能用更少的代码来实现这个功能

from subprocess import Popen, PIPE

def getstatusoutput(command):
    process = Popen(command, stdout=PIPE)
    out, _ = process.communicate()
    return (process.returncode, out)

code, out = getstatusoutput(["echo", "some text"])
print code
print out

0

getstatusoutput的作用是将stdout和stderr输出交错在一个变量中收集起来。这将相当接近于在那些不存在getstatusoutput的情况下(在Python 3中完全删除了getstatusoutput和整个commands模块),实际上复制了getstatusoutput的行为,除了换行符的行为。结果数据是以字节形式表示。

def getstatusoutput(cmd):
    subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    out, _ = process.communicate()

    if out[-1:] == b'\n':
        out = out[:-1]

    return (process.returncode, out)

这个函数在 Python 3 中有意返回 bytes,因为 Python 2 版本返回的是 str



0

Popen 是一种不错且易于实现的方式:

from subprocess import Popen, PIPE

def local(command):
    print 'local', local
    process = Popen(command.split(), stdout=PIPE, stderr=PIPE)
    out = process.stdout.read()
    err = process.stderr.read()
    print 'out', out
    print 'err', err
    returncode = process.wait()
    if returncode:
        raise Exception(returncode, err)
    else:
        return out

如果子进程生成足够的输出以填充stderr的操作系统管道缓冲区,则您的代码会发生死锁。 - jfs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接