“Pipe stderr, and not stdout” not working in Zsh

风流意气都作罢 提交于 2019-12-11 15:27:18

问题


How to pipe stderr, and not stdout? perfecly captures my problem, and the first answer is exactly how I initially tried to solve it:

(echo stdout; echo 1>&2 stderr) 2>&1 >/dev/null | less

(The subshell command with echos is a minimal placeholder thanks to user1934428 to demonstrate the issue; my actual problem has a more useful command, but one that everyone else can't run.)

However, it doesn't work: It's showing both stdout and stderr together. If I remove the pipe, it works as expected, only showing stderr. Eventually I realized this might be a shell thing, and tried bash: It worked perfectly there. I'm using Zsh: what about Zsh makes this fail?


回答1:


This is due to MULTIOS, which duplicates the output streams when you supply multiple redirections. Pipes are implicit redirections.

Type ls >/dev/null | less in your zsh and you will see output even though you redirected it. That's multios duplicating the stream.

unsetopt multios will provide the desired behaviour. This is quite a handy feature if I wouldn't always forget about it until it irritates me.

http://zsh.sourceforge.net/Doc/Release/Redirection.html#Multios




回答2:


Both behave the same for me, in that they only show stderr.

For testing, I created a command which outputs to stdout and stderr, and works the same in Zsh and bash:

(echo stdout; echo 1>&2 stderr)

prints

stdout
stderr

Now I do your redirection:

 (echo stdout; echo 1>&2 stderr) 2>&1 >/dev/null

Here, I see on bash and zsh

stderr

but of course written to standard output, because 2>&1 first redirects the stderr of the command to what is at the moment standard output, and then discards the standard output of the command.



来源:https://stackoverflow.com/questions/58019928/pipe-stderr-and-not-stdout-not-working-in-zsh

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!