Tuberías tanto stdout y stderr en bash?


Parece que las versiones más recientes de bash tienen el operador &>, que (si entiendo correctamente), redirige tanto stdout como stderr a un archivo (&>> se añade al archivo en su lugar, como aclaró Adrian).

¿Cuál es la forma más sencilla de lograr lo mismo, sino de canalizar a otro comando?

Por ejemplo, en esta línea:

cmd-doesnt-respect-difference-between-stdout-and-stderr | grep -i SomeError

Me gustaría que el grep coincidiera en el contenido tanto en stdout como en stderr (efectivamente, combinarlos en uno solo flujo).

Nota: esta pregunta es acerca de la tubería, no redireccionamiento - por lo que no es un duplicado de la pregunta que actualmente está marcado como un duplicado de.

Author: Andrew Ferrier, 2013-05-11

2 answers

(Nótese que &>>file añade a un archivo mientras que &> redireccionaría y sobrescribiría un archivo previamente existente.)

Para combinar stdout y stderr redirigir este último al primero usando 2>&1. Esto redirige stderr (descriptor de archivo 2) a stdout (descriptor de archivo 1), por ejemplo:

$ { echo "stdout"; echo "stderr" 1>&2; } | grep -v std
stderr
$

stdout va a stdout, stderr va a stderr. grep solo ve stdout, por lo tanto stderr imprime en la terminal.

Por otro lado:

$ { echo "stdout"; echo "stderr" 1>&2; } 2>&1 | grep -v std
$

Después al escribir tanto en stdout como en stderr, 2>&1 redirige stderr de nuevo a stdout y grep ve ambas cadenas en stdin, por lo tanto filtra ambas.

Puede leer más sobre la redirección aquí.

Con respecto a su ejemplo (POSIX):

cmd-doesnt-respect-difference-between-stdout-and-stderr 2>&1 | grep -i SomeError

O, usando >=bash-4:

cmd-doesnt-respect-difference-between-stdout-and-stderr |& grep -i SomeError
 121
Author: Adrian Frühwirth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-09 11:56:57

Bash tiene una abreviatura para 2>&1 |, a saber |&, que canaliza tanto stdout como stderr (ver el manual ):

cmd-doesnt-respect-difference-between-stdout-and-stderr |& grep -i SomeError

Esto se introdujo en Bash 4.0, ver las notas de la versión .

 65
Author: Benjamin W.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-14 02:49:03