Comment créer une boucle dans bash qui attend la réponse d'un serveur Web?

104

Comment créer une boucle dans bash qui attend la réponse d'un serveur Web?

Il doit imprimer un "." toutes les 10 secondes environ, et attendez que le serveur commence à répondre.

Mise à jour, ce code teste si j'obtiens une bonne réponse du serveur.

if curl --output / dev / null --silent --head --fail "$ url"; puis
  echo "L'URL existe: $ url"
autre
  echo "L'URL n'existe pas: $ url"
Fi
Sorin
la source
Pouvez-vous être plus précis sur la façon dont vous attendez que le serveur réponde?
chepner
Je considérerai que le serveur n'est pas prêt, tant qu'il ne répond pas ou qu'il répond avec quelque chose de différent d'une réponse 200.
sorin le

Réponses:

170

En combinant la question avec la réponse de Chepner, cela a fonctionné pour moi:

until $(curl --output /dev/null --silent --head --fail http://myhost:myport); do
    printf '.'
    sleep 5
done
Thomas Ferris Nicolaisen
la source
10
L'utilisation de backticks `` est obsolète . Utilisez $( )plutôt.
Serge Stroobandt
6
Ce serait une excellente extension pour permettre un temps d'attente maximum avant d'abandonner
tkruse
Pourquoi avez-vous besoin d'un --head?
lexicore
3
@lexicore Puisque le corps n'est pas intéressant pour cette commande, nous demandons seulement la tête (bien que vous puissiez inclure la logique pour vérifier plus de choses sur l'état du serveur). Laisser de côté --headne changerait rien, mais vous pourriez le faire si vous voulez exercer une certaine logique sur le contenu de la réponse (comme un status.html).
Thomas Ferris Nicolaisen
1
J'ai eu un cas particulier où l'utilisation --headrevenait toujours 405. Dû le supprimer pour le faire fonctionner
Ron Harlev
38

Je voulais limiter le nombre maximum de tentatives. Sur la base de la réponse acceptée de Thomas, j'ai fait ceci:

attempt_counter=0
max_attempts=5

until $(curl --output /dev/null --silent --head --fail http://myhost:myport); do
    if [ ${attempt_counter} -eq ${max_attempts} ];then
      echo "Max attempts reached"
      exit 1
    fi

    printf '.'
    attempt_counter=$(($attempt_counter+1))
    sleep 5
done
illagrenan
la source
Je suggère d'ajouter --max-time 5si pour certaines raisons demandées le lien
expire
16

httping est bien pour cela. simple, propre, calme.

while ! httping -qc1 http://myhost:myport ; do sleep 1 ; done

tandis que / jusqu'à ce que etc est une préférence personnelle.

Bruce Edge
la source
2
À la réflexion, pour toujours, c'est long ... for i in seq 60; do httping -qc1 http://myhost:myport && echo && break sleep 5 echo -n ${i}.. done
Bruce Edge
2

L'utilisation de backticks ` `est obsolète . Utilisez à la $( )place:

until $(curl --output /dev/null --silent --head --fail http://myhost:myport); do
  printf '.'
  sleep 5
done
Serge Stroobandt
la source
0

Puzzle intéressant. Si vous n'avez pas d'accès ou d'API asynchrone avec votre client, vous pouvez essayer de grepping vos sockets TCP comme ceci:

until grep '***IPV4 ADDRESS OF SERVER IN REVERSE HEX***' /proc/net/tcp
do
  printf '.'
  sleep 1
done

Mais c'est une attente chargée avec des intervalles de 1 seconde. Vous voulez probablement plus de résolution que cela. C'est aussi mondial. Si une autre connexion est établie avec ce serveur, vos résultats ne sont pas valides.

BoeroBoy
la source
-1

si vous avez besoin de vérifier si le serveur est disponible, la cause redémarre ou autre chose, vous pouvez essayer de faire un wget sur le serveur et d'analyser la réponse ou l'erreur, si vous obtenez un 200 ou même un 404, le serveur est en marche, vous pourrait changer le délai d'expiration wget avec --timeout = secondes, vous pouvez définir le délai d'expiration à 10 secondes et faire une boucle jusqu'à ce que le grep sur la réponse ait un résultat.

Je ne sais pas si c'est ce que vous recherchez ou si vous avez vraiment besoin du code bash.

Caillot
la source