忽略subprocess.Popen的输出

Rom*_*dgz 10 python subprocess

我从我的Python脚本调用java程序,它输出了许多我不想要的无用信息.我试过了对Popen stdout=None函数的addind :

subprocess.Popen(['java', '-jar', 'foo.jar'], stdout=None)
Run Code Online (Sandbox Code Playgroud)

但它也是如此.任何的想法?

aba*_*ert 34

3.3文档:

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

所以:

subprocess.check_call(['java', '-jar', 'foo.jar'], stdout=subprocess.DEVNULL)
Run Code Online (Sandbox Code Playgroud)

这仅存在于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)
Run Code Online (Sandbox Code Playgroud)

请注意,如果您正在做一些不适合单行的更复杂的事情,您需要devnullPopen对象的整个生命周期中保持开放,而不仅仅是它的构造.(也就是说,将整个内容放在with声明中.)

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

缺点是,理论上,subprocess可能在一些os.devnull没有的平台上工作.如果您只关心POSIX和Windows,PyPy和Jython(大多数人)的CPython,这将永远不会成为问题.对于其他情况,请在分发代码之前进行测试.


Mar*_*ers 6

文档:

使用默认设置None,不会发生重定向.

您需要设置stdoutsubprocess.PIPE,然后调用.communicate()和简单地忽略捕获的输出.

p = subprocess.Popen(['java', '-jar', 'foo.jar'], stdout=subprocess.PIPE)
p.communicate()
Run Code Online (Sandbox Code Playgroud)

虽然我怀疑使用的subprocess.call()东西足以满足您的需求:

subprocess.call(['java', '-jar', 'foo.jar'], stdout=subprocess.PIPE)
Run Code Online (Sandbox Code Playgroud)

  • 创建和忽略管道通常是有效的,但是如果写入过多会导致子进程阻塞(当然它可能会对您的系统起作用并且对您的某个用户失败),所以我认为它确实不是这里只是`call`而不是`communic`是安全的.这就是为什么添加`DEVNULL`的原因 - 所以你_can_只是`call`而不用担心它.(嗯,这是稍微复杂的情况,你设置`stderr = DEVNULL`但不是`stdout`,只是`check_output`.但同样的想法.) (5认同)