¿Cómo puedo canalizar solo stderr en zsh?

18

En bash:

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

Mientras que en zsh:

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

¿Hay alguna manera de canalizar solo el error estándar mientras se redirige la salida estándar?

Tavian Barnes
fuente

Respuestas:

22

Con zsh y con la mult_iosopción activada ( activada de forma predeterminada), en:

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

El 1> /dev/null | cates visto como una redirección múltiple de echostdout de.

Entonces echo, stdout ahora se redirige a ambos /dev/nully a una tubería a cat(como si se estuviera usando tee).

Para cancelar esa redirección múltiple, puede hacer:

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

Es decir, cerrar stdout (cancelar la tubería) antes de redirigir a /dev/null

O use un grupo de comandos o subshell como:

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

De esa manera, la salida echoestándar solo se redirige explícitamente una vez (la redirección de la tubería se aplica al grupo / subshell y se hereda por echo).

O puede deshabilitar por multioscompleto:

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

Alternativamente, podría usar la sustitución de procesos en lugar de una tubería:

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

Sin embargo, tenga en cuenta que cuando el control de trabajo está desactivado (como en los scripts), el catproceso se ejecutará de forma asincrónica (como si se iniciara con &).

Stéphane Chazelas
fuente
3
¡Gracias! Otra forma de evitarlo es (echo hi 2>&1 1>/dev/null) | cat.
Tavian Barnes
1
@TavianBarnes, buen punto, gracias. Lo he agregado a la respuesta para completar. También funciona con un grupo de comando ( {echo...}|cat)
Stéphane Chazelas