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

要实现同样的任务,而不是通过管道连接到另一个命令,最简单的方法是什么?

例如,在这一行中:

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

我想让grep匹配stdout和stderr中的内容(有效地,将它们合并到一个流中)。

注意:这个问题问的是管道,而不是重定向——所以它不是当前标记为重复的问题的副本。


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

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

$ { 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
$

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

你可以在这里阅读更多关于重定向的信息。

关于你的例子(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

Bash有2>&1 |的简写,即|&,它同时传递stdout和stderr(参见手册):

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

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