用bash管道stdout和stderr?

Piping both stdout and stderr in bash?

新版本的bash似乎有&>操作符,它(如果我理解正确的话)将stdout和stderr都重定向到一个文件(&>>将附加到文件中,正如adrian所阐明的那样)。

要实现相同的目标,最简单的方法是什么,而不是通过管道发送到另一个命令?

例如,在此行中:

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

我希望grep能够匹配stdout和stderr中的内容(实际上,将它们组合成一个流)。

注意:此问题询问的是管道,而不是重定向-因此它不是当前标记为的问题的副本。


(请注意,&>>file附加到文件,而&>将重定向并覆盖以前存在的文件。)

要将stdoutstderr结合起来,您可以使用2>&1将后者重定向到前者。这会将stderr(文件描述符2)重定向到stdout(文件描述符1),例如:

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

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

另一方面:

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

在写入stdout和stderr之后,2>&1将stderr重定向回stdout,grep在stdin上看到这两个字符串,从而将两者都过滤掉。

您可以在这里阅读更多关于重定向的内容。

关于您的示例(posix):

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

或者,使用>=bash-4

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


bash有一个2>&1 |的缩写,即|&,它将stdout和stderr连接起来(参见手册):

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

这是在bash 4.0中引入的,请参见发行说明。