2013-02-06 69 views
9

我从我的Python脚本调用了一个java程序,并且它输出了许多我不想要的无用信息。我曾尝试addind stdout=None到Popen功能:忽略subprocess的输出.Popen

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

但它的确如此。任何想法?

回答

31

3.3 documentation

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

所以:

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)中的好处是,你没有创建不必要的管道,而且,更重要的是,可以” t运行到边界情况,其中子进程阻塞写入该管道。

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

+0

+1:devnull。确保'devnull'在子进程处于活动状态时保持打开状态(with-statement意味着否则)。最后一段看起来没有必要:DEVNULL通过CPython中的os.devnull实现。 os.devnull与Jython一起使用。 – jfs

+0

@ J.F.Sebastian:在'check_call'(在​​'with'内)之后,'devnull'不再需要。但是,是的,也许我应该澄清,对于不适合单一行的更复杂的用例,整个事情需要放在'with'内,而不仅仅是'Popen'。 – abarnert

+0

@JFSebastian:与此同时,对于'os.devnull',它是否确实存在于每个有“子进程”存在的平台上,因此不需要“在使用前检查”,或者你知道它也存在在Jython上,因此我应该将Jython移动到您不需要检查的平台列表中? – abarnert

6

documentation

随着None默认设置,不会发生重定向。

您需要设置stdoutsubprocess.PIPE,然后调用.communicate(),只要忽略捕获输出。

p = subprocess.Popen(['java', '-jar', 'foo.jar'], stdout=subprocess.PIPE) 
p.communicate() 

虽然我怀疑使用比就足够了subprocess.call()更适合您的需要:

subprocess.call(['java', '-jar', 'foo.jar'], stdout=subprocess.PIPE) 
+1

@sjtaheri:谢谢你的纠正,我自己申请了。 –

+4

创建和忽略管道通常是有效的,但是如果它写得太多(当然它可能在你的系统上工作并且对你的一个用户失败),它可能导致子进程阻塞,所以我认为它确实不是一个'在这里只是“通话”而不是“通信”。这就是为什么'DEVNULL'被添加了 - 所以你只能'调用'而不用担心它。 (好吧,在稍微复杂的情况下,你设置了'stderr = DEVNULL',而不是'stdout',只是'check_output'。但是同样的想法。) – abarnert

+0

@abarnert:啊,没有意识到已经添加了;只是在Python 3文档中找到它。 –