Shell: redirect stdout to /dev/null and stderr to stdout
bash, linux, sh, shell
Solution
You want
./script 2>&1 1>/dev/null | ./other-script
The order here is important. Let's assume stdin (fd 0), stdout (fd 1) and stderr (fd 2) are all connected to a tty initially, so
0: /dev/tty, 1: /dev/tty, 2: /dev/tty
The first thing that gets set up is the pipe. other-script's stdin gets connected to the pipe, and script's stdout gets connected to the pipe, so script's file descriptors so far look like:
0: /dev/tty, 1: pipe, 2: /dev/tty
Next, the redirections occur, from left to right. `2>&1` makes fd 2 go wherever fd 1 is currently going, which is the pipe.
0: /dev/tty, 1: pipe, 2: pipe
Lastly, `1>/dev/null` redirects fd1 to `/dev/null`
0: /dev/tty, 1: /dev/null, 2: pipe
End result, script's stdout is silenced, and its stderr is sent through the pipe, which ends up in other-script's stdin.
Also see http://bash-hackers.org/wiki/doku.php/howto/redirection_tutorial
Also note that `1>/dev/null` is synonymous to, but more explicit than `>/dev/null`
Problem
I saw this interesting question at a comment on cyberciti.biz. That I found I even can't find a flexible way to do this in one-line command with sh. As far my thought for the solution is: ``` tmp_file=`mktemp` (./script 2>$tmp_file >/dev/null; cat $tmp_file) | ./other-script rm tmp_file ``` But you see, this is not synchronous, and fatally, it's so ugly. Welcome to share you mind about this. :)