Reputation: 43427
I use zsh at the command-line but the shell scripts I write run bash so that they are portable.
I was learning about IO redirection from here when I realized this difference:
Note that the command is just an arbitrary one whose first line of output is over stderr and the second line comes over stdout.
zsh
on OS X:
% ls -ld /tmp /tnt 1>&2 2>&1 | sed -e 's/^/++/'
ls: /tnt: No such file or directory
++ls: /tnt: No such file or directory
lrwxr-xr-x@ 1 root wheel 11 Oct 19 2012 /tmp -> private/tmp
++lrwxr-xr-x@ 1 root wheel 11 Oct 19 2012 /tmp -> private/tmp
bash
:
bash-3.2$ ls -ld /tmp /tnt 1>&2 2>&1 | sed -e 's/^/++/'
ls: /tnt: No such file or directory
lrwxr-xr-x@ 1 root wheel 11 Oct 19 2012 /tmp -> private/tmp
I'm having a hard time figuring out zsh
's output.
Also, on a Linux the output order's slightly different for zsh
:
% ls -ld /tmp /tnt 1>&2 2>&1 | sed -e 's/^/++/'
ls: cannot access /tnt: No such file or directory
drwxrwxrwt. 13 root root 4096 Dec 19 23:11 /tmp
++ls: cannot access /tnt: No such file or directory
++drwxrwxrwt. 13 root root 4096 Dec 19 23:11 /tmp
bash
output is identical though.
More experimentation in zsh
:
% ls -ld /tmp /tnt 1>&2 | sed -e 's/^/++/'
ls: /tnt: No such file or directory
lrwxr-xr-x@ 1 root wheel 11 Oct 19 2012 /tmp -> private/tmp
++lrwxr-xr-x@ 1 root wheel 11 Oct 19 2012 /tmp -> private/tmp
% ls -ld /tmp /tnt 2>&1 | sed -e 's/^/++/'
++ls: /tnt: No such file or directory
++lrwxr-xr-x@ 1 root wheel 11 Oct 19 2012 /tmp -> private/tmp
That last one there produces identical results to bash
.
I figure I should prefer learning bash
's behavior inside-out before delving into how zsh
ticks, but this isn't really ideal because chances are at least half of the IO redirection I expect to be doing will be spur-of-the-moment hacks that I surely will want to try from the zsh
prompt. And I'm actually pretty invested in zsh
because I have a ton of custom plugins and it would be a major effort at this point to do a big switch back to bash.
Upvotes: 0
Views: 930
Reputation: 6239
That's due to zsh
's mult_ios feature.
In zsh
, when a fd is redirected twice, zsh
implements an internal tee
:
ls > foo > bar
Sends the output of ls
to a pipe and zsh
feeds it to both foo
and bar
.
It can get confusing with pipes.
ls > foo | cmd
Sends the output to both foo
and cmd
.
You can disable it with:
setopt no_mult_ios
Upvotes: 3