有没有子过程调用的安静版本?

有没有一种 subprocess.call的变体,可以运行命令而不打印到标准输出,或一种方法来阻止它的标准输出消息?

46375 次浏览

是的,把它的 stdout重定向到 /dev/null

process = subprocess.call(["my", "command"], stdout=open(os.devnull, 'wb'))

通常这种闲聊是来自 stderr,所以你可能想要沉默太多。自 Python 3.3以来,subprocess.call直接具有以下特性:

若要禁止 stdout 或 stderr,请提供值 DevNull

用法:

import subprocess
rc = subprocess.call(args, stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)

如果你还在使用 Python 2:

import os, subprocess


with open(os.devnull, 'wb') as shutup:
rc = subprocess.call(args, stdout=shutup, stderr=shutup)

这是我经常使用的配方: 调用 subprocess并收集输出,当命令成功时丢弃输出,但是当命令失败时打印输出。

import subprocess as sp
import sys


if "print" in __builtins__.__dict__:
prn = __builtins__.__dict__["print"]
else:
def prn(*args, **kwargs):
"""
prn(value, ..., sep=' ', end='\\n', file=sys.stdout)
Works just like the print function in Python 3.x but can be used in 2.x.


Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file: a file-like object (stream); defaults to the current sys.stdout.
sep:  string inserted between values, default a space.
end:  string appended after the last value, default a newline.
"""
sep = kwargs.get("sep", ' ')
end = kwargs.get("end", '\n')
file = kwargs.get("file", sys.stdout)


s = sep.join(str(x) for x in args) + end
file.write(s)




def rc_run_cmd_basic(lst_cmd, verbose=False, silent=False):
if silent and verbose:
raise ValueError("cannot specify both verbose and silent as true")


p = sp.Popen(lst_cmd, stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.PIPE)
tup_output = p.communicate()


s_cmd = ' '.join(lst_cmd)
if verbose:
prn()
prn("command: '%s'\n" % s_cmd)


if 0 != p.returncode:
prn()
prn("Command failed with code %d:" % p.returncode)
else:
prn("Command succeeded!  code %d" % p.returncode)
if verbose:
prn("Output for: " + s_cmd)
prn(tup_output[0])
prn()
if not silent and 0 != p.returncode:
prn("Error output for: " + s_cmd)
prn(tup_output[1])
prn()


return p.returncode

在这种情况下,我使用 subprocess.check _ output 并删除返回值。您可能需要添加一条注释,说明为什么使用 check _ output 代替 check _ call。当出现故障并且您对错误输出感兴趣时,check _ output 也会更好。下面的示例代码。只有在取消注释打印行时才能看到输出。如果命令失败,将引发异常。

import subprocess
ret = subprocess.check_output(["cat", "/tmp/1"])
#print ret