zsh I / O重定向:重定向然后进行管道;到底是怎么回事?


8

有人可以解释一下此命令中发生的情况:

echo foo >&2 | grep foo

Zsh(5.0.2)打印foo两次。看似一个到标准输出,另一个到标准错误,因为运行了以下命令:

{ echo foo >&2 | grep foo } >/dev/null

和:

{ echo foo >&2 | grep foo } 2>/dev/null

两者都只打印foo一次。

Answers:


5

那就是MULTIOS的效果。

echo foo >&2 | grep foo

将写入foostderr并通过管道foo传输到grep。由于stderr默认为terminal,因此您将看到两foo行,一行来自echo,一行来自grep结果。

{ echo foo >&2 | grep foo } >/dev/null

在这里,您看到了一行,因为stdout被重定向到/dev/null,您只看到了foo从的行echo

{ echo foo >&2 | grep foo } 2>/dev/null

在这里,您看到了一行,因为stderr被重定向到了/dev/null,您只看到了foo从的行grep

您可以通过线路输出颜色轻松查看端子的差异。grep将突出显示匹配的模式(或者您可以通过使用强制使用--color=always)。


MULTIOS默认情况下启用,nomultios且未设置选项:

$ unsetopt | grep nomultios
nomultios

要禁用它,只需设置nomultios选项:

$ setopt nomultios

啊,我不知道zsh可以做到!我(基本上)了解重定向,{echo foo >&2} | grep foo如果您看到我要说的话,我想知道为什么该命令不等同于。我以为我在上面询问的命令会将stdout重定向到stderr,然后将空的stdout用管道传输到grep。
Zorawar 2015年

@Zorawar:您的帖子中未解决该问题,因此我将在此处回答。在中{echo foo >&2} | grep foo{echo foo >&2}被视为命令,它在子shell中运行。你可以认为它像A | grep foo哪里A{echo foo >&2}。在这种情况下,>&2|分离,MULTIOS在这里有没有效果。
cuonglm

@Zorawar这种情况是为什么我最终关闭multios的原因。这是一个可爱的主意,但实际上,我发现它通常很烦人,很少有用。
吉尔斯(Gillles)“所以别再作恶了”

@cuonglm,我在这里有另一个问题,但没有得到任何答案。如果您知道并且也有时间,可以请您帮忙吗?
刘莎
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.