18

In bash:

$ echo hi 2>&1 1>/dev/null | cat
$

While in zsh:

$ echo hi 2>&1 1>/dev/null | cat
hi
$

Is there a way to pipe only standard error while redirecting standard out?

22

With zsh and with the mult_ios option on (on by default), in:

echo hi 2>&1 1>/dev/null | cat

The 1> /dev/null | cat is seen as a multiple redirection of echo's stdout.

So echo's stdout is now redirected to both /dev/null and a pipe to cat (as if using tee).

To cancel that multiple redirection, you can do:

echo hi 2>&1 >&- > /dev/null | cat

That is, closing stdout (cancelling the piping) before redirecting to /dev/null

Or use a command group or subshell like:

{echo hi 2>&1 1>/dev/null} | cat 
(echo hi 2>&1 1>/dev/null) | cat

That way, echo's stdout is only redirected explicitly once (the pipe redirection is applied to the group/subshell and inherited by echo).

Or you can disable multios altogether:

(setopt nomultios; echo hi 2>&1 > /dev/null | cat)

Alternatively, you could use process substitution instead of a pipe:

echo hi 2> >(cat) > /dev/null

Beware however that when job control is off (like in scripts), the cat process will be running asynchronously (as if started with &).

  • 3
    Thanks! Another way to get around it is (echo hi 2>&1 1>/dev/null) | cat. – Tavian Barnes Feb 23 '16 at 14:54
  • 1
    @TavianBarnes, good point, thanks. I've added it to the answer for completeness. It also works with a command group ({echo...}|cat) – Stéphane Chazelas Feb 23 '16 at 15:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.