Quando o GNU greptenta gravar seu resultado, ele falhará com um status de saída diferente de zero, porque não tem onde gravar a saída, porque a conexão SSH se foi.
Isso significa que a ifdeclaração está sempre assumindo o elseramo.
Para ilustrar isso (isso não é exatamente o que está acontecendo no seu caso, mas mostra o que acontece se o GNU grepnão conseguir gravar sua saída):
$ echo 'hello' | grep hello >&- 2>&-
$ echo $?
2
Aqui, procuramos grepa string que echoproduz, mas fechamos os dois fluxos de saída para grepque ele não possa gravar em nenhum lugar. Como você pode ver, o status de saída do GNU grepé 2 em vez de 0.
Isso é particular do GNU grep, grepnos sistemas BSD não se comportará da mesma maneira:
$ echo 'hello' | grep hello >&- 2>&- # using BSD grep here
$ echo $?
0
Para remediar isso, verifique se o script não gera saída. Você pode fazer isso com exec >/dev/null 2>&1. Além disso, devemos usar grepcom essa -qopção, pois não estamos interessados em ver a saída dele (isso geralmente também acelera o processo grep, pois não precisa analisar o arquivo inteiro, mas, nesse caso, faz muito pouco diferença de velocidade, já que o arquivo é muito pequeno).
Em resumo:
#!/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
Você também pode usar um teste pingdiretamente, removendo a necessidade de um dos arquivos intermediários (e também se livrando do outro arquivo intermediário que realmente contém apenas um carimbo de data):
#!/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
Nas duas variações do script acima, optei por sair do loop quando não alcançava o host, apenas para minimizar o número de emails enviados. Em vez disso, você pode substituir breakpor, por exemplo, sleep 10mou algo assim, se espera que o servidor volte a aparecer novamente.
Também ajustei levemente as opções usadas, pingpois -i 1não faz muito sentido -c 1.
Menor (a menos que você queira continuar enviando e-mails quando o host estiver inacessível):
#!/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 um trabalho cron executado a cada minuto (continuaria enviando e-mails a cada minuto se o servidor continuar inativo):
* * * * * ping -q -c 1 -W 1 >/dev/null 2>&1 || ( date | mail -s "Server down" myemail@address.com )
:faz? Não faria sentido para mim que fosse um ponto e vírgula;...