Como posso canalizar apenas stderr no zsh?

18

Na festança:

$ echo hi 2>&1 1>/dev/null | cat
$

Enquanto estiver no zsh:

$ echo hi 2>&1 1>/dev/null | cat
hi
$

Existe uma maneira de canalizar apenas o erro padrão ao redirecionar a saída padrão?

Tavian Barnes
fonte

Respostas:

22

Com zsh e com a mult_iosopção ativada (ativada por padrão), em:

echo hi 2>&1 1>/dev/null | cat

O 1> /dev/null | caté visto como um redirecionamento múltiplo do echostdout.

Portanto, echo's stdout agora é redirecionado para ambos /dev/nulle um tubo para cat(como se estivesse usando tee).

Para cancelar esse redirecionamento múltiplo, você pode:

echo hi 2>&1 >&- > /dev/null | cat

Ou seja, fechando o stdout (cancelando a tubulação) antes de redirecionar para /dev/null

Ou use um grupo de comandos ou subshell como:

{echo hi 2>&1 1>/dev/null} | cat 
(echo hi 2>&1 1>/dev/null) | cat

Dessa forma, echoo stdout do s é redirecionado apenas explicitamente uma vez (o redirecionamento de canal é aplicado ao grupo / subshell e herdado por echo).

Ou você pode desativar multioscompletamente:

(setopt nomultios; echo hi 2>&1 > /dev/null | cat)

Como alternativa, você pode usar a substituição do processo em vez de um pipe:

echo hi 2> >(cat) > /dev/null

Cuidado, no entanto, quando o controle de tarefas estiver desativado (como nos scripts), o catprocesso será executado de forma assíncrona (como se iniciado &).

Stéphane Chazelas
fonte
3
Obrigado! Outra maneira de contornar isso é (echo hi 2>&1 1>/dev/null) | cat.
Tavian Barnes
11
@TavianBarnes, bom ponto, obrigado. Adicionei-o à resposta para completar. Também funciona com um grupo de comando ( {echo...}|cat)
Stéphane Chazelas 23/02