zsh I / O redirection: перенаправление и затем конвейерная обработка; что здесь происходит?

8

Может кто-нибудь объяснить, что происходит в этой команде:

echo foo >&2 | grep foo

Zsh (5.0.2) печатает fooдважды. Один, по-видимому, для stdout, а другой - для stderr, так как выполняет эти команды:

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

а также:

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

оба просто распечатать fooодин раз.

Зоравар
источник

Ответы:

5

Это эффект MULTIOS .

echo foo >&2 | grep foo

напишет fooв stderr, а также трубу fooк grep. Так как stderr по умолчанию использует терминал, вы увидите две 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опцией unset:

$ unsetopt | grep nomultios
nomultios

Чтобы отключить его, просто установите nomultiosопцию:

$ setopt nomultios
cuonglm
источник
Ах, я не знал, что Zsh может сделать это! Я (в основном) понимаю перенаправление, я хотел знать, почему команда не эквивалентна {echo foo >&2} | grep foo, если вы видите, что я пытаюсь сказать. Я думал, что команда, о которой я спрашивал выше, перенаправит stdout в stderr, а затем перенаправит пустой stdout в grep.
Zorawar
@Zorawar: Этот вопрос не был рассмотрен в вашем сообщении, поэтому я отвечу здесь. В {echo foo >&2} | grep foo, {echo foo >&2}был рассмотрен как команда, и он работал в подоболочке. Вы можете думать , что нравится , A | grep fooгде Aэто {echo foo >&2}. В этом случае >&2и |были отделены, MULTIOSздесь не действует.
cuonglm
@Zorawar Вот почему я отключил мультиосети. Это милая идея, но на практике я нашел ее часто раздражающей и редко полезной.
Жиль "ТАК - перестань быть злым"
@cuonglm, у меня есть еще один вопрос, который задают здесь, но не получили никакого ответа. Если вы это знаете и у вас есть время, не могли бы вы помочь?
Лю Ша