Esse é o efeito do MULTIOS .
echo foo >&2 | grep foo
irá escrever foopara stderr e também canalizar foopara grep. Como stderr assume como padrão o terminal, você verá duas foolinhas, uma de echo, uma do grepresultado.
{ echo foo >&2 | grep foo } >/dev/null
Aqui, você viu uma linha porque o stdout foi redirecionado para /dev/null, apenas a foolinha de echo.
{ echo foo >&2 | grep foo } 2>/dev/null
Aqui, você viu uma linha porque o stderr foi redirecionado /dev/null, você só viu a foolinha de grep.
Você pode ver facilmente a diferença no terminal pela cor de saída da linha. grepdestacará o padrão correspondente (ou você pode forçá-lo usando --color=always).
MULTIOSfoi ativado por padrão com a nomultiosopção não configurada:
$ unsetopt | grep nomultios
nomultios
Para desativá-lo, basta definir a nomultiosopção:
$ setopt nomultios
{echo foo >&2} | grep foo, se você vê o que estou tentando dizer. Eu pensei que o comando que eu perguntei acima teria redirecionado o stdout para o stderr e, em seguida, transferiu o stdout vazio para o grep.