Reputation: 93
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?
Upvotes: 3
Views: 422
Reputation: 438178
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.
Upvotes: 4
Reputation: 531345
Turning off the MULTIOS option changes this behavior.
% echo xxx >&2 | wc
xxx
1 1 4
% setopt NOMULTIOS
% echo xxx >&2 | wc
xxx
0 0 0
With the option set, a single command can have multiple IO redirections, and for this purpose, it appears the pipe counts as one.
Upvotes: 3