It's well known how to pipe the standard ouput of a process into another processes standard input:

proc1 | proc2

But what if I want to send the standard error of proc1 to proc2 and leave the standard output going to its current location? You would think bash would have a command along the lines of:

proc1 2| proc2

But, alas, no. Is there any way to do this?

+5  A: 

You can use the following trick to swap stdout and stderr. Then you just use the regular pipe functionality.

( proc1 3>&1 1>&2- 2>&3- ) | proc2

Provided stdout and stderr both pointed to the same place at the start, this will give you what you need.

What it does:

  • 3>&1 creates a new file handle 3 which is set to the current 1 (original stdout) just to save it somewhere.
  • 1>2- sets stdout to got to the current file handle 2 (original stderr) then closes 2.
  • 2>3- sets stderr to got to the current file handle 3 (original stdout) then closes 3.

It's effectively the swap command you see in sorting:

temp   = value1;
value1 = value2;
value2 = temp;
+2  A: 

Bash 4 has this feature:

If `|&' is used, the standard error of command1 is connected to command2's standard input through the pipe; it is shorthand for 2>&1 |. This implicit redirection of the standard error is performed after any redirections specified by the command.

zsh also has this feature.

Dennis Williamson
From reading the docs, that does both standard error *and* output as opposed to just stderr, but it's nice to know. Time to start looking at bash 4, I think.