用bash管道stdout和stderr?

And*_*ier 141 bash stdout stderr piping

似乎较新版本的bash具有&>运算符,如果我理解正确的话,将stdout和stderr重定向到一个文件(&>>改为附加到文件,就像Adrian澄清的那样).

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

例如,在这一行:

cmd-doesnt-respect-difference-between-stdout-and-stderr | grep -i SomeError
Run Code Online (Sandbox Code Playgroud)

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

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

Adr*_*rth 150

(注意,在重定向和覆盖以前存在的文件时&>>file 附加到文件.)&>

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

$ { echo "stdout"; echo "stderr" 1>&2; } | grep -v std
stderr
$
Run Code Online (Sandbox Code Playgroud)

stdout去stdout,stderr去stderr.grep只看到stdout,因此stderr打印到终端.

另一方面:

$ { echo "stdout"; echo "stderr" 1>&2; } 2>&1 | grep -v std
$
Run Code Online (Sandbox Code Playgroud)

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

你可以阅读更多有关重定向这里.

关于你的例子(POSIX):

cmd-doesnt-respect-difference-between-stdout-and-stderr 2>&1 | grep -i SomeError
Run Code Online (Sandbox Code Playgroud)

或者,使用>=bash-4:

cmd-doesnt-respect-difference-between-stdout-and-stderr |& grep -i SomeError
Run Code Online (Sandbox Code Playgroud)

  • 我在你的答案中添加了你的例子,以防万一根据我给出的例子不明显.作为附注,您还可以使用特定于bash的`|&'而不是`2>&1 |`. (16认同)
  • 关于@AdrianFrühwirth为未来读者提出的快捷方式`|&`的旁注:这个功能只有`bash`版本4+支持.如果你使用3或以下,你必须坚持使用'2>&1 |`. (13认同)
  • Bash重定向[这里很好地解释](http://www.catonmat.net/blog/bash-one-liners-explained-part-three/).@AdrianFrühwirth做得很好,粘贴的链接更进一步.有时,我希望官方的Bash文档很好. (3认同)

Ben*_* W. 98

Bash有一个简写2>&1 |,即|&stdout和stderr的管道(参见手册):

cmd-doesnt-respect-difference-between-stdout-and-stderr |& grep -i SomeError
Run Code Online (Sandbox Code Playgroud)

这是在Bash 4.0中引入的,请参阅发行说明.

  • 最值得注意的是,在macOS上发布的Bash太旧了,无法支持这一点. (7认同)