似乎较新版本的 bash 有
&>
运算符,它(如果我理解正确的话)将 stdout 和 stderr 重定向到一个文件(&>>
附加到文件,而不是附加到文件,正如 Adrian 所澄清的那样)。
实现相同目标但通过管道传输到另一个命令的最简单方法是什么?
例如,在这一行中:
cmd-doesnt-respect-difference-between-stdout-and-stderr | grep -i SomeError
我希望 grep 能够匹配 stdout 和 stderr 中的内容(实际上,将它们组合成一个流)。
注意:这个问题询问的是管道,不是重定向 - 所以它不是当前标记为重复的问题的重复。
(请注意,
&>>file
追加到文件,而&>
将重定向并覆盖以前存在的文件。)
要组合
stdout
和 stderr
,您可以使用 1>&2
将后者重定向到前者。这会将 stdout(文件描述符 1)重定向到 stderr(文件描述符 2),例如:
$ { echo "stdout"; echo "stderr" 1>&2; } | grep -v std
stderr
$
stdout
转到标准输出,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
如果您想将 STDOUT 和 STDERR 传输到 different 子 shell,而不是两者都传输到同一个子 shell(如
|&
/ 2>&1
所做的那样),我使用这个:
producer \
> >( stdout_pipeline... ) \
2> >( stderr_pipeline... ) \
...
虽然这使用了重定向运算符,但它使用底层的管道将生产者连接到子 shell。
您可以通过这种方式处理多个输出流(2不是限制),也可以使用企鹅运算符(
[n]< <(...)
)以类似的方式从子shell传输(可能是多个)输入流。