Quando o GNU grep
tenta 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 if
declaração está sempre assumindo o else
ramo.
Para ilustrar isso (isso não é exatamente o que está acontecendo no seu caso, mas mostra o que acontece se o GNU grep
não conseguir gravar sua saída):
$ echo 'hello' | grep hello >&- 2>&-
$ echo $?
2
Aqui, procuramos grep
a string que echo
produz, mas fechamos os dois fluxos de saída para grep
que 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
, grep
nos 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 grep
com essa -q
opçã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 ping
diretamente, 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 break
por, por exemplo, sleep 10m
ou algo assim, se espera que o servidor volte a aparecer novamente.
Também ajustei levemente as opções usadas, ping
pois -i 1
nã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;
...