Cuando GNU grep
intenta escribir su resultado, fallará con un estado de salida distinto de cero, porque no tiene donde escribir la salida, porque la conexión SSH se ha ido.
Esto significa que la if
declaración siempre toma la else
rama.
Para ilustrar esto (esto no es exactamente lo que está sucediendo en su caso, pero muestra lo que sucede si GNU grep
no puede escribir su salida):
$ echo 'hello' | grep hello >&- 2>&-
$ echo $?
2
Aquí estamos grep
para la cadena que echo
produce, pero cerramos ambas secuencias de salida para grep
que no pueda escribir en ningún lado. Como puede ver, el estado de salida de GNU grep
es 2 en lugar de 0.
Esto es particular de GNU grep
, grep
en los sistemas BSD no se comportará igual:
$ echo 'hello' | grep hello >&- 2>&- # using BSD grep here
$ echo $?
0
Para remediar esto, asegúrese de que el script no genere resultados. Puedes hacer esto con exec >/dev/null 2>&1
. Además, deberíamos usarlo grep
con su -q
opción, ya que no estamos interesados en ver el resultado (generalmente esto también aceleraría, grep
ya que no necesita analizar todo el archivo, pero en este caso hace muy poco) diferencia en velocidad ya que el archivo es muy pequeño).
En breve:
#!/bin/sh
# redirect all output not redirected elsewhere to /dev/null by default:
exec >/dev/null 2>&1
while true; do
date >sdown.txt
ping -c 1 -W 1 myserver.net >pingop.txt
if ! grep -q "64 bytes" pingop.txt; then
mutt -s "Server Down!" myemail@address.com <sdown.txt
break
fi
sleep 10
done
También puede usar una prueba ping
directamente, eliminando la necesidad de uno de los archivos intermedios (y también deshaciéndose del otro archivo intermedio que realmente solo contiene una marca de fecha):
#!/bin/sh
exec >/dev/null 2>&1
while true; do
if ! ping -q -c 1 -W 1 myserver.net; then
date | mutt -s "Server Down!" myemail@address.com
break
fi
sleep 10
done
En ambas variaciones de la secuencia de comandos anterior, elijo salir del ciclo en caso de que no llegue al host, solo para minimizar la cantidad de correos electrónicos enviados. En su lugar, podría reemplazar el break
con eg sleep 10m
o algo así si espera que el servidor finalmente vuelva a aparecer.
También he modificado ligeramente las opciones utilizadas, ping
ya -i 1
que no tiene mucho sentido -c 1
.
Más breve (a menos que desee que continúe enviando correos electrónicos cuando no se pueda acceder al host):
#!/bin/sh
exec >/dev/null 2>&1
while ping -q -c 1 -W 1 myserver.net; do
sleep 10
done
date | mutt -s "Server Down!" myemail@address.com
Como un trabajo cron que se ejecuta cada minuto (continuaría enviando correos electrónicos cada minuto si el servidor continúa inactivo):
* * * * * ping -q -c 1 -W 1 >/dev/null 2>&1 || ( date | mail -s "Server down" myemail@address.com )
:
? Para mí tendría sentido que fuera un punto y coma;
...