Differences in I / O redirection between zsh and bash

I use zsh on the command line, but I write run bash shell scripts so that they are portable.

I found out about IO redirection from here when I realized this difference:

Note that the command is just arbitrary, the first line of which is above stderr, and the second line is above 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 find it difficult to determine the output of zsh .

Also, on Linux, the output order is 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.

More experiments 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 

This last gives the same results for bash .

I suppose I should prefer to learn bash behavior inside out before delving into how zsh ticking, but thatโ€™s not entirely ideal, because the odds are at least half the IO redirection that I expect to be, which I I definitely want to try from the zsh invitation. And in fact, I really invested in zsh , because I have a ton of custom plugins, and at that point it would be a big step to make a big switch to bash.

0
source share
1 answer

This is due to the zsh mult_ios function .

In zsh , when fd is redirected twice, zsh implements an internal tee :

 ls > foo > bar 

Sends ls output to a channel, and zsh passes it to both foo and bar .

He may get confused with the pipes.

 ls > foo | cmd 

Sends output to foo and cmd .

You can disable it with:

 setopt no_mult_ios 
+1
source

Source: https://habr.com/ru/post/985641/


All Articles