当前位置:  开发笔记 > 编程语言 > 正文

如何将STDERR重定向到STDOUT,但忽略原始STDOUT?

如何解决《如何将STDERR重定向到STDOUT,但忽略原始STDOUT?》经验,为你挑选了1个好方法。

我有一个程序,其STDERR输出我想检查和运行grep等.

所以我可以将它重定向到STDOUT并使用grep,但问题是,我想要原始STDOUT内容.

所以,这个不会做

cmd 2>&1 | grep pattern

因为它会混合原始的STDOUT和STDERR.

而且这个不起作用,因为grep没有读取STDERR输出:

cmd 1>/dev/null | grep pattern

但是,这个也行不通:

cmd 1>/dev/null 2>&1 | grep pattern

因为输出将完全为空,因为所有内容都被写入/dev/null.

但必须有一个简单的方法来做到这一点?



1> Tom Alsberg..:

什么行不通:

你引用的最后一个命令的原因:

cmd 1>/dev/null 2>&1 | grep pattern

不起作用,源于对重定向工作顺序的混淆.您希望最后引用的重定向应用于每个输出之前的重定向,以便输出原始标准输出文件描述符(1)将转到/ dev/null,并输出到标准错误文件描述符(2)将转到原始标准输出.

但是,这不是shell重定向的工作原理.每个重定向导致文件描述符被"重新映射"通过关闭"源"和复制"目的地"进去(看man的网页dup(2)close(2)),为了.这意味着在您的命令中,标准输出首先被替换为/dev/null,然后标准输出/dev/null已经替换为标准输出.

什么有效:

因此,要获得所需的效果,您只需要反转重定向.然后你会有标准错误转到标准输出,原始标准输出转到/dev/null:

cmd 2>&1 >/dev/null | grep pattern

(注意1前面>是不必要的 - 输出重定向标准输出是默认的)


附录:Charlie提到重定向&-到关闭文件描述符.如果使用支持该扩展的交互式shell(bash以及其他一些实现但不是全部,并且它不是标准的),您也可以这样做:

cmd 2>&1 >&- | grep pattern

这可能会更好 - 它可以节省一些时间,因为当命令尝试写入标准输出时,调用write可能会立即失败而无需等待上下文切换到内核和驱动程序处理/dev/null(取决于系统调用实现 - 有些可能在libc函数中捕获这个,有些也可能有特殊处理/dev/null).如果有很多输出是值得的,那么键入的速度会更快.

这将主要起作用,因为大多数程序不关心它们是否无法写入标准输出(谁真正检查返回值printf?)并且不介意标准输出被关闭.但是如果write失败,一些程序可以使用失败代码进行挽救- 通常会阻止处理器,程序使用一些仔细的I/O库或记录到标准输出.因此,如果它不起作用,请记住这是一个可能的原因并尝试/dev/null.

推荐阅读
农大军乐团_697
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有