¿Cómo redirigir la salida de cualquier comando?

14

Estoy tratando de escribir un script simple para monitorear el estado de mi red, sin todos pinglos resultados de:

ping -q -c 1 google.com > /dev/null && echo online || echo offline

El problema es que cuando no estoy conectado, sigo recibiendo un mensaje de error en mi salida:

ping: unknown host google.com
offline

¿Cómo puedo mantener este mensaje de error fuera de mi salida?

operalala
fuente

Respuestas:

28

Cuando corres:

ping -q -c 1 google.com > /dev/null && echo online || echo offline

Básicamente, solo está redirigiendo la salida de Stream 1 (es decir stdout) a /dev/null.

Esto está bien cuando desea redirigir la salida producida por la ejecución normal de un programa. Sin embargo, en caso de que también desee redirigir la salida causada por todos los errores, advertencias o fallas, también debe redirigir la stderrsecuencia o Error estándar a /dev/null.

Una forma de hacerlo es anteponer el número de la secuencia que desea redirigir al operador de redirección, de >esta manera:Command 2> /dev/null

Por lo tanto, su comando se vería así:

ping -q -c 1 google.com > /dev/null 2> /dev/null && echo online || echo offline

Pero tenga en cuenta que ya hemos redirigido una transmisión a /dev/null. ¿Por qué no simplemente a cuestas en la misma redirección? Bash nos permite hacer esto especificando el número de transmisión al que redirigir. 2>&1.

Observe el &carácter después del operador de redirección. Esto le dice al shell que lo que aparece a continuación no es un nombre de archivo, sino un identificador para la secuencia de salida.

ping -q -c 1 google.com > /dev/null 2>&1  echo online || echo offline

Tenga cuidado con los operadores de redireccionamiento, su orden es muy importante. Si fuera a redirigir en el orden incorrecto, obtendrá resultados inesperados.

Otra forma en la que puede lograr un silencio completo es redirigiendo todas las secuencias de salida para /dev/nullusar este acceso directo: &>/dev/null(o redirigir a un archivo de registro con &>/path/to/file.log).

Por lo tanto, escriba su comando como:

ping -q -c 1 google.com &> /dev/null && echo online || echo offline
Darnir
fuente
1
Ajá &>/dev/nulllo es. ¡Gracias a todos por la ayuda instantánea!
operalala
44
Be careful with the redirection operators, their order matters a lot., pero no 2>&1
incluiste
¡Había olvidado agregar eso! Respuesta editada para reflejar el ejemplo. Cuando tenga un poco más de tiempo en mis manos, explicaré cómo funciona el pedido también.
darnir
9

Debe redirigir tanto la salida estándar ( >o 1>) como el error estándar ( 2>):

ping -q -c 1 google.com > /dev/null 2>/dev/null && echo online || echo offline

o, redirigir uno al otro:

ping -q -c 1 google.com > /dev/null 2>&1 && echo online || echo offline
terdon
fuente
8
$ ping -q -c 1 google.com > /dev/null 2>&1 && echo online || echo offline

Ejemplos

$ ping -q -c 1 google.com > /dev/null 2>&1 && echo online || echo offline
online

$ ping -q -c 1 googleadf.com > /dev/null 2>&1 && echo online || echo offline
offline

Acelerando el ping

Dependiendo de su pingimplementación, puede estar limitado a un solo recuento -c 1. Algunas implementaciones te permitirán ir por debajo de esto, pero esencialmente tienes que esperar a que las malas búsquedas terminen. Entonces, en lugar de usar, pinges posible que desee usar fingen su lugar.

lentitud del fallo del ping

$ date; ping -q -c 1 google.com > /dev/null 2>&1 && echo online || echo offline; date
Tue Jan 28 13:51:10 EST 2014
online
Tue Jan 28 13:51:10 EST 2014

$ date; ping -q -c 1 googleadf.com > /dev/null 2>&1 && echo online || echo offline; date
Tue Jan 28 13:51:15 EST 2014
offline
Tue Jan 28 13:51:25 EST 2014

Fing es mucho más rápido para fallar

$ date; fing -p google.com > /dev/null 2>&1 && echo online || echo offline; date
Tue Jan 28 13:49:21 EST 2014
online
Tue Jan 28 13:49:22 EST 2014

$ date; fing -p googleadf.com > /dev/null 2>&1 && echo online || echo offline; date
Tue Jan 28 13:49:35 EST 2014
online
Tue Jan 28 13:49:38 EST 2014
slm
fuente
1
Prefiero usar el timecomando que calcular manualmente la diferencia horaria con date:time { fing -p googleadf.com > /dev/null 2>&1 && echo online || echo offline; }
Ruslan
@Ruslan: gracias, lo hice de esta manera porque quería la salida date. Es más fácil, en mi opinión, que alguien más lea el resultado generado.
slm