Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Zsh output redirection behavior

In bash:

bash% echo xxx >&2 | wc
xxx
   0   0   0

In zsh:

zsh% echo xxx >&2 | wc
xxx
   1   1   4
zsh% { echo xxx >&2; } | wc
xxx
   0   0   0

How do I make zsh behave like bash for this case? Is there a zsh option to set?

like image 729
aggu Avatar asked Dec 14 '25 13:12

aggu


1 Answers

To change the behavior ad-hoc, you can simply parenthesize:

(echo xxx >&2) | wc

Note that there is no side effect from parenthesizing here, as even without it your commands run in subshells, due to use of a pipe (|).

To change the behavior for the entire shell, see @chepner's answer.


Performance considerations:

@chepner asks in a comment whether the parentheses result in an additional subshell (and thus child process).

The surprising answer is the opposite:
With option MULTIOS ON (the default), using parentheses results in 1 fewer subshell.

With option MULTIOS OFF, the parentheses (which are then not needed) make no difference.


How I tested:

On OS X 10.9.2, I used sudo dtruss -t fork -f -p {pidOfZsh} to monitor fork() calls in a zsh shell; zsh version is zsh 5.0.2 (x86_64-apple-darwin13.0).

With option MULTIOS ON, echo xxx >&2 | wc forked 3 times, while (echo xxx >&2) | wc only forked 2 times.

like image 122
mklement0 Avatar answered Dec 16 '25 09:12

mklement0



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!