Piping stderr in unix

Posted: 26th May 2011 by Tim in Bash, Ubuntu
Tags: , , , , , , , , ,

In unix, you can pass output from one program to another using the pipe symbol (|). Unfortunately, it only pipes the output from stdout (cout). You can pass the output from both stdout and stderr (cerr) by adding 2>&1 to the end of the command before the pipe, where 1 is the file descriptor for stdout and 2 is the file descriptor for stderr (this redirects stderr to stdout). But what if you only want to pipe the output from stderr?

The answer is to use a third file descriptor. For example, the following code:

(time sleep 1) 3>&1 1>&2 2>&3 | grep real

Will display the ‘real’ time the computer took to sleep for 1 second. Basically, the time command prints timing info to stderr. Here, we redirect stdout (1) to stderr (2), stderr to the new file descriptor (3) and, finally, send the temporary file descriptor to stdout. With this only the stderr will be piped to grep.

It looks convoluted and confusing, but it works and doesn’t require temporary files or anything else.