Essayer ici d'écrire un script shell qui continue de tester mon serveur et de m'envoyer un e-mail lorsqu'il tombe en panne.
Le problème est que lorsque je me déconnecte de la connexion ssh, malgré son exécution &
à la fin de la commande, comme ./stest01.sh &
, il tombe automatiquement dans autre chose et continue de me poster sans interruption, jusqu'à ce que je me reconnecte et le tue.
#!/bin/bash
while true; do
date > sdown.txt ;
cp /dev/null pingop.txt ;
ping -i 1 -c 1 -W 1 myserver.net > pingop.txt &
sleep 1 ;
if
grep "64 bytes" pingop.txt ;
then
:
else
mutt -s "Server Down!" myemail@address.com < sdown.txt ;
sleep 10 ;
fi
done
linux
shell-script
grep
ping
Vasconcelos1914
la source
la source
:
? Ça aurait du sens pour moi s'il s'agissait d'un point-virgule;
...:
ne fait rien. C'est ce pour quoi il est conçu. Ici, au lieu d'inverser le test, ils l'utilisent pour faire un no-op auparavantelse
.Réponses:
Lorsque GNU
grep
essaie d'écrire son résultat, il échouera avec un état de sortie différent de zéro, car il n'a nulle part où écrire la sortie, car la connexion SSH a disparu.Cela signifie que l'
if
instruction prend toujours laelse
branche.Pour illustrer cela (ce n'est pas exactement ce qui se passe dans votre cas, mais cela montre ce qui se passe si GNU
grep
n'est pas en mesure d'écrire sa sortie):Ici, nous
grep
pour la chaîne quiecho
produit, mais nous fermons les deux flux de sortie pourgrep
qu'il ne puisse écrire nulle part. Comme vous pouvez le voir, l'état de sortie de GNUgrep
est 2 plutôt que 0.Ceci est particulier à GNU
grep
,grep
sur les systèmes BSD ne se comportera pas de la même manière:Pour y remédier, assurez-vous que le script ne génère pas de sortie. Vous pouvez le faire avec
exec >/dev/null 2>&1
. De plus, nous devrions utilisergrep
avec son-q
option car nous ne sommes pas du tout intéressés à voir la sortie de celui-ci (cela accélérerait également généralement legrep
car il n'a pas besoin d'analyser tout le fichier, mais dans ce cas, cela fait très peu différence de vitesse car le fichier est si petit).En bref:
Vous pouvez également utiliser un test
ping
directement, supprimant le besoin d'un des fichiers intermédiaires (et supprimant également l'autre fichier intermédiaire qui ne contient vraiment qu'un horodatage):Dans les deux variantes du script ci-dessus, j'ai choisi de quitter la boucle en cas d'échec pour atteindre l'hôte, juste pour minimiser le nombre d'e-mails envoyés. Vous pouvez à la place remplacer le
break
par exemplesleep 10m
ou quelque chose si vous vous attendez à ce que le serveur réapparaisse finalement.J'ai également légèrement modifié les options utilisées avec
ping
car cela-i 1
n'a pas beaucoup de sens-c 1
.Plus court (sauf si vous souhaitez qu'il continue à envoyer des e-mails lorsque l'hôte est inaccessible):
En tant que tâche cron exécutée toutes les minutes (continuerait d'envoyer des e-mails toutes les minutes si le serveur continuait à être en panne):
la source
>&-
fermera le fd (comme dans, le descripteur de fichier 1 est fermé), tandis que la fermeture de la connexion SSH aura un effet différent (un descripteur de fichier sera toujours là, mais pas connecté à quoi que ce soit de l'autre côté.) Je pense que le point se tient toujours, ce qui est que GNU grep quitte non nul s'il essaie d'écrire la sortie et cela échoue. Oui, la meilleure solution consiste simplement à vérifier directement l'état de sortie du ping.exec </dev/null >/dev/null 2>&1
près du début. De cette façon, si par exempleping
décide d'écrire quelque chose sur stderr, cela ne posera pas de problème./dev/null
ici, mais j'ai trié la sortie. Merci pour la suggestion.