忽略subprocess.Popen的输出


问题内容

这个问题已经在这里有了答案

如何读取子进程的stdout的第一个字节,然后在Python中丢弃其余字节?
(2个答案)

5年前关闭。

我正在从我的Python脚本中调用一个Java程序,并且它输出了许多我不需要的无用信息。我试过addindstdout=None到Popen函数:

subprocess.Popen(['java', '-jar', 'foo.jar'], stdout=None)

但是它也一样。任何想法?


问题答案:

3.3文档

stdin,stdout和stderr分别指定执行程序的标准输入,标准输出和标准错误文件句柄。有效值为PIPE,DEVNULL,现有文件描述符(正整数),现有文件对象和无。

所以:

subprocess.check_call(['java', '-jar', 'foo.jar'], stdout=subprocess.DEVNULL)

仅在3.3及更高版本中存在。但是文档说:

DEVNULL表示将使用特殊文件os.devnull。

并且os.devnull存在回到2.4(以前subprocess存在)的方式。因此,您可以手动执行相同的操作:

with open(os.devnull, 'w') as devnull:
    subprocess.check_call(['java', '-jar', 'foo.jar'], stdout=devnull)

请注意,如果您要做的事情比较复杂而又不能容纳在一行中,那么就需要devnullPopen对象的整个生命中保持开放,而不仅仅是其构造。(也就是说,将整个内容放入with语句中。)

重定向到/dev/null(POSIX)或NUL:(Windows)的优点是您不会创建不必要的管道,更重要的是,不会遇到子进程在写入该管道时阻塞的情况。

从理论上讲,缺点是subprocess可能os.devnull无法在某些平台上运行。如果您只关心POSIX和Windows上的CPython,PyPy和Jython(您中的大多数人),那么这将永远不是问题。对于其他情况,请在分发代码之前进行测试。