How can I pipe stderr, and not stdout?
First redirect stderr to stdout — the pipe; then redirect stdout to /dev/null
(without changing where stderr is going):
command 2>&1 >/dev/null | grep 'something'
For the details of I/O redirection in all its variety, see the chapter on Redirections in the Bash reference manual.
Note that the sequence of I/O redirections is interpreted left-to-right, but pipes are set up before the I/O redirections are interpreted. File descriptors such as 1 and 2 are references to open file descriptions. The operation 2>&1
makes file descriptor 2 aka stderr refer to the same open file description as file descriptor 1 aka stdout is currently referring to (see dup2()
and open()
). The operation >/dev/null
then changes file descriptor 1 so that it refers to an open file description for /dev/null
, but that doesn't change the fact that file descriptor 2 refers to the open file description which file descriptor 1 was originally pointing to — namely, the pipe.
Or to swap the output from standard error and standard output over, use:
command 3>&1 1>&2 2>&3
This creates a new file descriptor (3) and assigns it to the same place as 1 (standard output), then assigns fd 1 (standard output) to the same place as fd 2 (standard error) and finally assigns fd 2 (standard error) to the same place as fd 3 (standard output).
Standard error is now available as standard output and the old standard output is preserved in standard error. This may be overkill, but it hopefully gives more details on Bash file descriptors (there are nine available to each process).
In Bash, you can also redirect to a subshell using process substitution:
command > >(stdlog pipe) 2> >(stderr pipe)
For the case at hand:
command 2> >(grep 'something') >/dev/null
Combining the best of these answers, if you do:
command 2> >(grep -v something 1>&2)
...then all stdout is preserved as stdout and all stderr is preserved as stderr, but you won't see any lines in stderr containing the string "something".
This has the unique advantage of not reversing or discarding stdout and stderr, nor smushing them together, nor using any temporary files.