Commande / script shell pour voir si un hôte est vivant?

9

J'essaie de trouver plus de façons de voir si un hôte donné est en place, en utilisant uniquement des commandes shell (principalement bash). Idéalement, il serait capable de fonctionner avec les noms d'hôte et les adresses IP. À l'heure actuelle, la seule façon native que je connaisse est le ping, peut-être intégré dans un script comme décrit ici. D'autres idées?

user67459
la source

Réponses:

7

ping est le moyen de tester si un hôte est vivant et connecté. (Si un hôte est vivant mais déconnecté ou lent à répondre, vous ne pouvez pas le distinguer de sa mort.)

Les options prises en charge par la pingcommande varient d'un système à l'autre. Vous voudrez vous assurer qu'il ne boucle pas indéfiniment mais qu'il revient après quelques secondes s'il n'a pas reçu de réponse.

Avec FreeBSD et Linux iputils, ping -c 1 -W 1 >/dev/nullenvoie un seul ping et attendez 1 seconde. Vous n'avez pas besoin d'analyser la sortie: la commande retourne 0 si elle a reçu un ping back et non nul sinon (nom d'hôte inconnu, pas de route vers l'hôte, pas de réponse). Certaines implémentations peuvent nécessiter des drapeaux différents (par exemple -wau lieu de -WFreeBSD), consultez le manuel de votre système.

if ping -c 1 -W 1 "$hostname_or_ip_address"; then
  echo "$hostname_or_ip_address is alive"
else
  echo "$hostname_or_ip_address is pining for the fjords"
fi
Gilles 'SO- arrête d'être méchant'
la source
Je sais que c'est le chemin, j'espérais juste que ce n'était pas le seul moyen, même si les autres moyens sont étranges ou capricieux ou quoi d'autre. Tant pis!
user67459
2
Cette réponse n'aurait PAS dû être marquée comme answeredréponse. Le PO a expressément demandé more ways to see if a given host is up, sauf avec ping, que cette réponse ne fournit pas.
Yokai
De la page de manuel 'ping':"Because of the load it can impose on the network, it is unwise to use ping during normal operations or from automated scripts."
1111161171159459134
@ 1111161171159459134 Ce paragraphe aurait pu être mieux rédigé. C'est trop alarmiste. Vous ne devriez pas faire de pings ou de pings avec un taux très élevé, mais un paquet ping de temps en temps est négligeable.
Gilles 'SO- arrête d'être méchant'
2

Ping est idéal pour obtenir une réponse rapide quant à savoir si l'hôte est connecté au réseau, mais il ne vous indiquera pas souvent si l'hôte est vivant ou non, ou s'il fonctionne toujours comme prévu. Cela est dû au fait que les réponses ping sont généralement gérées par le noyau, donc même si chaque application sur le système est tombée en panne (par exemple en raison d'une défaillance du disque ou d'un manque de mémoire), vous obtiendrez souvent des réponses ping et supposerez que la machine est fonctionne normalement lorsque la situation est tout à fait le contraire.

Vérification des services

Habituellement, vous ne vous souciez pas vraiment de savoir si un hôte est toujours en ligne ou non, ce qui vous importe vraiment, c'est de savoir si la machine effectue toujours une tâche. Donc, si vous pouvez vérifier la tâche directement, vous saurez que l'hôte est à la fois en place et que la tâche est toujours en cours d'exécution.

Pour un hôte distant qui exécute un serveur Web par exemple, vous pouvez faire quelque chose comme ceci:

# Add the -f option to curl if server errors like HTTP 404 should fail too
if curl -I "http://$TARGET"; then
  echo "$TARGET alive and web site is up"
else
  echo "$TARGET offline or web server problem"
fi

S'il exécute SSH et que vous avez configuré des clés pour la connexion sans mot de passe, vous avez quelques options supplémentaires, par exemple:

if ssh "$TARGET" true; then
  echo "$TARGET alive and accessible via SSH"
else
  echo "$TARGET offline or not accepting SSH logins"
fi

Cela fonctionne en connectant SSH à l'hôte et en exécutant la truecommande, puis en fermant la connexion. La sshcommande ne renverra de succès que si cette commande a pu être exécutée avec succès.

Tests à distance via SSH

Vous pouvez l'étendre pour vérifier des processus spécifiques, par exemple en vous assurant qu'il mysqlds'exécute sur la machine:

if ssh "$TARGET" bash -c 'ps aux | grep -q mysqld'; then
  echo "$TARGET alive and running MySQL"
else
  echo "$TARGET offline or MySQL crashed"
fi

Bien sûr, dans ce cas, vous feriez mieux d'exécuter quelque chose comme monitsur la cible pour vous assurer que le service continue de fonctionner, mais cela est utile dans les scripts où vous ne souhaitez effectuer qu'une tâche sur la machine A tant que la machine B est prête pour cela .

Cela pourrait être quelque chose comme vérifier que la machine cible a un certain système de fichiers monté avant de lui faire un rsync, afin que vous ne remplissiez pas accidentellement son disque principal si un système de fichiers secondaire ne s'est pas monté pour une raison quelconque. Par exemple, cela s'assurera qu'il /mnt/raidest monté sur la machine cible avant de continuer.

if ssh "$TARGET" bash -c 'mount | grep -q /mnt/raid'; then
  echo "$TARGET alive and filesystem ready to receive data"
else
  echo "$TARGET offline or filesystem not mounted"
fi

Services sans client

Parfois, il n'y a pas de moyen facile de se connecter au service et vous voulez juste voir s'il accepte les connexions TCP entrantes, mais lorsque vous accédez telnetà la cible sur le port en question, il se trouve juste là et ne vous déconnecte pas, ce qui signifie que dans un script le ferait se bloquer.

Bien que ce ne soit pas aussi propre, vous pouvez toujours le faire à l'aide des programmes timeoutet netcat. Par exemple, cela vérifie si la machine accepte les connexions SMB / CIFS sur le port TCP 445, vous pouvez donc voir si elle exécute le partage de fichiers Windows même si vous n'avez pas de mot de passe pour vous connecter ou si les outils client CIFS ne sont pas '' t installé:

# Wait 1 second to connect (-w 1) and if the total time (DNS lookups + connect
# time) reaches 5 seconds, assume the connection was successful and the remote
# host is waiting for us to send data.  Connecting on TCP port 445.
if echo 'x' | timeout --preserve-status 5 nc -w 1 "$TARGET" 445; then
  echo "$TARGET alive and CIFS service available"
else
  echo "$TARGET offline or CIFS unavailable"
fi
Malvineous
la source