Cuando GNU grepintenta 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 ifdeclaración siempre toma la elserama.
Para ilustrar esto (esto no es exactamente lo que está sucediendo en su caso, pero muestra lo que sucede si GNU grepno puede escribir su salida):
$ echo 'hello' | grep hello >&- 2>&-
$ echo $?
2
Aquí estamos greppara la cadena que echoproduce, pero cerramos ambas secuencias de salida para grepque no pueda escribir en ningún lado. Como puede ver, el estado de salida de GNU grepes 2 en lugar de 0.
Esto es particular de GNU grep, grepen 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 grepcon su -qopción, ya que no estamos interesados en ver el resultado (generalmente esto también aceleraría, grepya 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 pingdirectamente, 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 breakcon eg sleep 10mo algo así si espera que el servidor finalmente vuelva a aparecer.
También he modificado ligeramente las opciones utilizadas, pingya -i 1que 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;...