J'écris sur un script qui redémarre différents serveurs. Après le redémarrage, je veux «attendre» jusqu'à ce que tous les serveurs soient de nouveau en ligne. (Pour garder les choses simples, j'ai défini pour moi en ligne = pingable)
Donc, pour chaque serveur que je fais
ServerXY_W=1
echo -n "waiting for ServerXY ..."
while (($ServerXY_W == 1))
do
if ping -c 1 -w 0.2 192.168.123.123 &> /dev/null
then
echo "ServerXY is back online!"
ServerXY_W=0
else
echo -n "."
fi
done
Ce à quoi je m'attendrais (et aimerais) serait une sortie comme par exemple
waiting for ServerXY .................
ServerXY is back online!
où les points .... apparaîtraient un par un.
Mais ce qui se passe réellement, c'est d'abord qu'il n'y a que
waiting for ServerXY ...
pendant un certain temps et quand le serveur est de retour, je reçois le dernier point et la dernière ligne comme
waiting for ServerXY ....
ServerXY is back online!
Pourquoi la boucle while n'est-elle exécutée que deux fois comme une fois avec l'échec du ping et une fois avec le ping qui réussit? Que dois-je changer pour ajouter plus de points dans la boucle while?
J'ai également fait le test avec une adresse IP inexistante. Mais il s'est coincé avec
waiting for NonExistentServer...
et jamais terminé bien sûr. Mais la même question, pourquoi ne pas ........
être ajouté?
Réponses:
Le problème
Le problème est que vous avez défini
-w 0.2
. Lorsque la valeur est inférieure à 1, les valeurs de délai (-w
) et de délai (-W
) sont ignorées. Cela a été mentionné précédemment dans cette question . Lorsque vous utilisez-w 1
, votre script (que j'ai légèrement modifié pour supprimer les bits inutiles) fonctionne correctement:Solution
La solution évidente est d'utiliser
-w 1
. Si vous avez l'intention d'utiliser une valeur inférieure à 1 seconde, latimeout
commande devrait être meilleure:Encore une fois, utilisez-le avec l'
!
opérateur dans la boucle:Bien sûr, le contraire peut être appliqué à l'affichage d'un message uniquement si le serveur est en marche et signaler quand le serveur tombe en panne, exemple:
Notez cependant que ce n'est pas parfait:
nous pingons avec seulement 1 paquet chaque seconde. Faible bande passante, mauvaise connectivité, mauvais matériel entre le serveur et le client cinglant le serveur déclenchera la boucle pour quitter et faire une fausse notification positive
Nous comptons sur le ping, qui utilise l'écho ICMP. Des pare-feu ou même des serveurs individuels bloquent les réponses aux échos ping / ICMP. Vous pouvez utiliser
nc
dencat
( ce qui est une version amélioréenc
). Quelque chose comme dans la boucle ci-dessus fonctionnera bien au lieu deping
:Ce que cela fait, c'est de se connecter au serveur sur 172.16.127.2 sur le port 80.
-z
c'est d'éviter les E / S - il suffit de se connecter et de se déconnecter.-w
est d'attendre 5 secondes avant de signaler l'échec de la connexion. Bien sûr, c'est un très bon choix lorsque vous avez un serveur sous votre contrôle et que vous savez que le port 80 est ouvert. UPD peut être utilisé correctement, mais s'il y a un pare-feu en place, TCP est probablement préféré.Un avantage caché ici est que si vous avez un service en cours d'exécution sur un port spécifique (tel que HTTP sur le port 80 ou RTSP sur 554), l'échec de la connexion au port peut servir d'indicateur que votre service a besoin d'un redémarrage.
Bien sûr,
nc
etping
peut être un peu spam. La meilleure façon serait d'avoir l'enregistrement du serveur avec un autre serveur central, d'envoyer un rapport périodique, peut-être toutes les heures; De cette façon, si votre serveur manque un "temps de punch", vous pouvez générer des erreurs. Le meilleur moyen est d'utiliser un service tel que Nagios, qui le fait. Mais à ce stade, nous entrons dans le domaine de l'informatique au niveau de l'entreprise avec plusieurs serveurs. Si vous avez quelque chose comme Raspberry Pi à la maison, vous n'avez probablement pas besoin de quelque chose de complexe.la source
while (( $ServerA_W==1 || $ServerB_W==1 || .....))
ce qui se passe lorsque chaque serveur est de retour.