在bash中管道stdout和stderr?

问题描述:

看来,较新版本的bash有&>运算符,如果我理解正确,运算符会将stdout和stderr重定向到一个文件(&>>附加到文件中,正如Adrian所阐明的那样)。在bash中管道stdout和stderr?

实现同样的事情最简单的方法是什么,而是用另一个命令管道?

例如,在这一行:

cmd-doesnt-respect-difference-between-stdout-and-stderr | grep -i SomeError 

我想要grep来既在stdout和stderr(有效,他们已组合成一个数据流)匹配的内容。

:这个问题问的管道,重定向 - 所以它不是它目前被标记为的重复问题的副本。

+0

请参阅第二个回答(https://stackoverflow.com/a/637834/1129642),了解正确连接标准输出和标准错误方式的链接问题。不需要另一个问题。 – Marki555 2016-07-15 08:25:31

+3

@triplee不完全重复,是吗?管道与重定向到文件? – 2016-07-26 14:02:49

+0

@BenjaminW至少有一个解决这两种情况的答案,尽管这不是被接受的答案。这是一个相当常见的问题,所以我们可能会找到更好的副本,或者让主持人合并这些副本 - 甚至在最糟糕的情况下,为这个主题制定一个全新的规范。如果你找到一个更好的欺骗,通过一切手段提出。提前致谢。 – tripleee 2016-07-26 16:33:59

(请注意,&>>file追加到一个文件,而&>会重定向和覆盖以前存在的文件。)

要结合stdoutstderr你会使用2>&1后者重定向到前者。此重定向标准错误(文件描述符2)到stdout(文件描述符1),例如:

$ { echo "stdout"; echo "stderr" 1>&2; } | grep -v std 
stderr 
$ 

stdout进入到stdout,stderr进入到stderr。 grep只看到stdout,因此stderr打印到终端。

在另一方面:

$ { echo "stdout"; echo "stderr" 1>&2; } 2>&1 | grep -v std 
$ 

写到标准输出和标准错误后,2>&1 stderr重定向回stdout和grep看到标准输入两个字符串,从而过滤掉两个。

您可以阅读更多关于重定向here

关于你的例子(POSIX):

cmd-doesnt-respect-difference-between-stdout-and-stderr 2>&1 | grep -i SomeError 

,或者使用>=bash-4

cmd-doesnt-respect-difference-between-stdout-and-stderr |& grep -i SomeError 
+0

感谢您澄清'&>>'。我纠正了我的问题。 – 2013-05-11 13:16:03

+14

我将你的例子添加到我的答案中,以防万一它根据我给出的例子不明显。作为一个旁注,你也可以使用特定于bash的'|&'而不是'2>&1 |'。 – 2013-05-11 13:21:22

+0

感谢您的澄清。有用的答案,谢谢。 – 2013-05-11 13:22:32

击具有用于2>&1 |,即|&的简写,其管输出和错误两者(见manual ):

cmd-doesnt-respect-difference-between-stdout-and-stderr |& grep -i SomeError 

这是在Bash 4.0中引入的,请参阅release notes

+0

感谢您补充完整性。我会保持其他答案的正确性,因为很多人仍然在4.0以前使用bash。但这很有用。 – 2016-05-09 09:30:54

+3

最值得注意的是,在macOS上运行的Bash太旧了,无法支持这一点。 – Flimm 2017-01-20 10:21:03

+0

@Flimm但zsh不是 – Trenton 2017-02-13 21:41:42