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).
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).
Note: this question is asking about piping, not redirecting - so it is not a duplicate of the question it's currently marked as a duplicate of.
(Note that &>>file
appends to a file while &>
would redirect and overwrite a previously existing file.)
To combine stdout
and stderr
you would redirect the latter to the former using 2>&1
. This redirects stderr (file descriptor 2) to stdout (file descriptor 1), e.g.:
$ { echo "stdout"; echo "stderr" 1>&2; } | grep -v std
stderr
$
stdout
goes to stdout, stderr
goes to stderr. grep
only sees stdout
, hence stderr
prints to the terminal.
On the other hand:
$ { echo "stdout"; echo "stderr" 1>&2; } 2>&1 | grep -v std
$
After writing to both stdout and stderr, 2>&1
redirects stderr back to stdout and grep
sees both strings on stdin, thus filters out both.
You can read more about redirection here.
Regarding your example (POSIX):
cmd-doesnt-respect-difference-between-stdout-and-stderr 2>&1 | grep -i SomeError
or, using >=bash-4
:
cmd-doesnt-respect-difference-between-stdout-and-stderr |& grep -i SomeError
Bash has a shorthand for 2>&1 |
, namely |&
, which pipes both stdout and stderr (see the manual):
cmd-doesnt-respect-difference-between-stdout-and-stderr |& grep -i SomeError
This was introduced in Bash 4.0, see the release notes.
来源:https://stackoverflow.com/questions/16497317/piping-both-stdout-and-stderr-in-bash