bashpipestdoutstderr

Piping both stdout and stderr in bash?


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

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

For example, in this line:

some-command | grep -i SomeError

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


Solution

  • To combine stdout and stderr you would redirect stderr to stdout using 2>&1:

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

    You can read more about redirection in the Bash manual: Redirections

    To elaborate

    This command group prints to stdout and stderr:

    $ { echo "stdout"; echo "stderr" 1>&2; }
    stdout
    stderr
    $ 
    

    When we pipe to grep, the pipe only redirects stdout to grep's stdin, thus grep only filters stdout.

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

    2>&1 redirects stderr back to stdout and grep sees both strings on stdin, thus filters out both.

    Regarding your example

    POSIX:

    some-command 2>&1 | grep -i SomeError
    

    or, using >=bash-4:

    some-command |& grep -i SomeError