J'ai un script qui crée une machine virtuelle et me donne une adresse IP. Ensuite, je voudrais faire quelque chose comme ça:
waitforssh 192.168.2.38 && ssh 192.168.2.38
Et cela attendra que la machine soit en place et SSH réagisse, puis SSH dessus.
Waitforsh est la commande que j'ai besoin de trouver.
Nmap, Netcat, fing ou ping ferait-il le travail? J'ai essayé Netcat mais cela abandonne seulement quelques secondes si l'hôte est inaccessible.
Il doit gérer le fait que la machine elle-même démarre et peut prendre un certain temps pour répondre aux paquets réseau.
Je n'ai pas d'hôte que je peux ssh et contrôler s'il s'agissait ou non, mais cela devrait fonctionner:
while ! ssh <ip>
do
echo "Trying again..."
done
Ou un script shell qui est plus explicite:
#!/bin/sh
ssh $1
while test $? -gt 0
do
sleep 5 # highly recommended - if it's in your local network, it can try an awful lot pretty quick...
echo "Trying again..."
ssh $1
done
Enregistrez-le comme (disons) waitforssh.sh
Et puis appelez-le avec sh waitforssh.sh 192.168.2.38
Eh bien, je ne suis pas sûr de ce que vous entendez par être up, mais qu'en est-il:
$ ping Host.com | grep --line-buffered "bytes from" | head -1 && ssh Host.com
Première commande ping | ... | head -1
attend que le serveur a envoyé une réponse ping unique et existe. Puis ssh entre en jeu. Sachez que grep
peut la sortie tampon, de sorte que c'est ce que --line-buffered
est pour.
Vous pouvez envelopper cette commande avec la fonction Bash pour l'utiliser exactement comme vous l'avez décrit.
$ waitfor() { ping $1 | grep --line-buffered "bytes from" | head -1 }
$ waitfor server.com && ssh server.com
Ceci est un script 'ping_ssh' que j'utilise. Il gère les cas de délai d'expiration, le succès rapide et ne pas demander des mots de passe ou ne sera pas conçu par le port étant ouvert mais ne répondant pas comme avec les solutions basées sur les "NC". Cela combine plusieurs réponses trouvées sur divers sites liés à Stackoverflow.
#!/usr/bin/bash
Host=$1
PORT=$2
#Host="localhost"
#PORT=8022
if [ -z "$1" ]
then
echo "Missing argument for Host."
exit 1
fi
if [ -z "$2" ]
then
echo "Missing argument for port."
exit 1
fi
echo "polling to see that Host is up and ready"
RESULT=1 # 0 upon success
TIMEOUT=30 # number of iterations (5 minutes?)
while :; do
echo "waiting for server ping ..."
# https://serverfault.com/questions/152795/linux-command-to-wait-for-a-ssh-server-to-be-up
# https://unix.stackexchange.com/questions/6809/how-can-i-check-that-a-remote-computer-is-online-for-ssh-script-access
# https://stackoverflow.com/questions/1405324/how-to-create-a-bash-script-to-check-the-ssh-connection
status=$(ssh -o BatchMode=yes -o ConnectTimeout=5 ${Host} -p ${PORT} echo ok 2>&1)
RESULT=$?
if [ $RESULT -eq 0 ]; then
# this is not really expected unless a key lets you log in
echo "connected ok"
break
fi
if [ $RESULT -eq 255 ]; then
# connection refused also gets you here
if [[ $status == *"Permission denied"* ]] ; then
# permission denied indicates the ssh link is okay
echo "server response found"
break
fi
fi
TIMEOUT=$((TIMEOUT-1))
if [ $TIMEOUT -eq 0 ]; then
echo "timed out"
# error for jenkins to see
exit 1
fi
sleep 10
done
La commande SSH peut recevoir une commande à effectuer sur la machine distante comme dernier paramètre. Alors appelez ssh $MACHINE echo
dans une boucle. Sur le succès, il retourne 0 en $ ?, à l'échec 255. Vous devez bien sûr utiliser l'authentification sans mots-mots avec des certificats.