如何在 zsh 中仅通过管道传输 stderr?

Tav*_*nes 23 shell zsh pipe io-redirection stderr

在 bash 中:

$ echo hi 2>&1 1>/dev/null | cat
$
Run Code Online (Sandbox Code Playgroud)

在 zsh 中:

$ echo hi 2>&1 1>/dev/null | cat
hi
$
Run Code Online (Sandbox Code Playgroud)

有没有办法在重定向标准输出时只传输标准错误?

Sté*_*las 26

使用 zsh 并打开mult_ios选项(默认情况下打开),在:

echo hi 2>&1 1>/dev/null | cat
Run Code Online (Sandbox Code Playgroud)

该1> /dev/null | cat被看作是一个多重定向echo的标准输出。

Soecho的标准输出现在被重定向到两者/dev/null和一个管道cat(就像使用tee)。

要取消多次重定向,您可以执行以下操作:

echo hi 2>&1 >&- > /dev/null | cat
Run Code Online (Sandbox Code Playgroud)

也就是说,在重定向到之前关闭标准输出(取消管道) /dev/null

或者使用命令组或子shell,如:

{echo hi 2>&1 1>/dev/null} | cat 
(echo hi 2>&1 1>/dev/null) | cat
Run Code Online (Sandbox Code Playgroud)

这样,echo的标准输出仅被显式重定向一次(管道重定向应用于组/子shell 并由 继承echo)。

或者您可以multios完全禁用:

(setopt nomultios; echo hi 2>&1 > /dev/null | cat)
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用进程替换而不是管道:

echo hi 2> >(cat) > /dev/null
Run Code Online (Sandbox Code Playgroud)

但是请注意,当作业控制关闭时(如在脚本中),该cat进程将异步运行(就像以 开头一样&)。

  • 谢谢!另一种绕过它的方法是`(echo hi 2>&1 1>/dev/null) | 猫`。 (3认同)
  • @TavianBarnes,好点,谢谢。为了完整性,我已将其添加到答案中。它还可以与命令组(`{echo...}|cat`)一起使用 (2认同)