在 bash 中同时传输标准输出和标准错误?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16497317/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 23:42:16  来源:igfitidea点击:

Piping both stdout and stderr in bash?

bashstdoutstderrpiping

提问by Andrew Ferrier

It seems that newer versions of bash have the &>operator, which (if I understand correctly), redirects both stdout and stderr to a file (&>>appends to the file instead, as Adrian clarified).

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

What's the simplest way to achieve the same thing, but instead piping to another command?

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

For example, in this line:

例如,在这一行中:

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

I'd like the grep to match on content both in stdout and stderr (effectively, have them combined into one stream).

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

Note: this question is asking about piping, notredirecting - so it is not a duplicate of the question it's currently marked as a duplicate of.

注意:这个问题是关于管道,而不是重定向 - 所以它不是它当前被标记为重复的问题的重复。

回答by Adrian Frühwirth

(Note that &>>fileappendsto a file while &>would redirect and overwritea previously existing file.)

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

To combine stdoutand stderryou would redirect the latter to the former using 2>&1. This redirects stderr (file descriptor 2) to stdout (file descriptor 1), e.g.:

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

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

stdoutgoes to stdout, stderrgoes to stderr. greponly sees stdout, hence stderrprints to the terminal.

stdout转到标准输出,stderr转到标准错误。grep只看到stdout,因此stderr打印到终端。

On the other hand:

另一方面:

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

After writing to both stdout and stderr, 2>&1redirects stderr back to stdout and grepsees both strings on stdin, thus filters out both.

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

You can read more about redirection here.

您可以在此处阅读有关重定向的更多信息。

Regarding your example (POSIX):

关于您的示例(POSIX):

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

or, using >=bash-4:

或者,使用>=bash-4

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

回答by Benjamin W.

Bash has a shorthand for 2>&1 |, namely |&, which pipes both stdout and stderr (see the manual):

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

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

This was introduced in Bash 4.0, see the release notes.

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