web-dev-qa-db-fra.com

Comment évaluer les codes de réponse http à partir du script bash / shell?

J'ai l'impression de passer à côté de l'évidence, mais je n'ai pas réussi avec man [curl|wget] ou Google ("http" est un terme de recherche tellement mauvais). Je cherche un correctif rapide et sale à l'un de nos serveurs Web qui échoue fréquemment, renvoyant le code d'état 500 avec un message d'erreur. Une fois que cela se produit, il doit être redémarré.

Comme la cause fondamentale semble être difficile à trouver, nous visons une solution rapide, en espérant qu'il suffira de passer le temps qu'il faut pour régler le problème au maximum (le service n'a pas besoin de la haute disponibilité).

La solution proposée consiste à créer un travail cron qui s'exécute toutes les 5 minutes en vérifiant http: // localhost: 8080 / . Si cela retourne avec le code d'état 500, le serveur Web sera redémarré. Le serveur redémarrera dans moins d'une minute, il n'est donc pas nécessaire de vérifier les redémarrages en cours.

Le serveur en question est une installation minimale d'ubuntu 8.04 avec juste assez de paquets installés pour exécuter ce dont il a actuellement besoin. Il n’existe aucune obligation importante d’exécuter la tâche dans bash, mais j’aimerais qu’il soit exécuté dans un environnement aussi minimaliste sans installer d’interprètes supplémentaires.

(Je connais suffisamment bien les scripts pour que la commande/les options permettant d'attribuer le code de statut http à une variable d'environnement suffisent - c'est ce que j'ai cherché et que je n'ai pas trouvé.)

173
Olaf Kock

Je n'ai pas testé cela sur un code 500, mais cela fonctionne sur d'autres comme 200, 302 et 404.

response=$(curl --write-out %{http_code} --silent --output /dev/null servername)

Comme suggéré par @ibai, ajoutez --head pour effectuer une demande HEAD uniquement. Cela permettra de gagner du temps lorsque la récupération est réussie car le contenu de la page ne sera pas transmis.

277
Dennis Williamson
curl --write-out "%{http_code}\n" --silent --output /dev/null "$URL"

travaux. Sinon, vous devez appuyer sur Entrée pour afficher le code lui-même.

38
hd1

Bien que le réponse acceptée soit une bonne réponse, il néglige les scénarios d'échec. curl renverra 000 en cas d'erreur dans la demande ou d'échec de la connexion.

url='http://localhost:8080/'
status=$(curl --head --location --connect-timeout 5 --write-out %{http_code} --silent --output /dev/null ${url})
[[ $status == 500 ]] || [[ $status == 000 ]] && echo restarting ${url} # do start/restart logic

Remarque: cela va un peu au-delà de la vérification de l'état demandée 500 pour confirmer également que curl peut même se connecter au serveur (c'est-à-dire renvoie 000).

Créez une fonction à partir de celle-ci:

failureCode() {
    local url=${1:-http://localhost:8080}
    local code=${2:-500}
    local status=$(curl --head --location --connect-timeout 5 --write-out %{http_code} --silent --output /dev/null ${url})
    [[ $status == ${code} ]] || [[ $status == 000 ]]
}

Testez l'obtention d'un 500:

failureCode http://httpbin.org/status/500 && echo need to restart

Testez l'erreur/échec de connexion (c'est-à-dire 000):

failureCode http://localhost:77777 && echo need to start

Testez ne pas obtenir un 500:

failureCode http://httpbin.org/status/400 || echo not a failure
17
nicerobot

J'avais besoin de démo quelque chose rapidement aujourd'hui et est venu avec cela. J'ai pensé le placer ici si quelqu'un avait besoin de quelque chose de similaire à la demande du PO.

#!/bin/bash

status_code=$(curl --write-out %{http_code} --silent --output /dev/null www.bbc.co.uk/news)

if [[ "$status_code" -ne 200 ]] ; then
  echo "Site status changed to $status_code" | mail -s "SITE STATUS CHECKER" "[email protected]" -r "STATUS_CHECKER"
else
  exit 0
fi

Cela enverra une alerte par e-mail à chaque changement d'état à partir de 200. C'est donc stupide et potentiellement gourmand. Pour améliorer cela, je regarderais en boucle plusieurs codes d'état et effectuons différentes actions en fonction du résultat.

17
Chris Gillatt

Avec netcat et awk, vous pouvez gérer la réponse du serveur manuellement:

if netcat 127.0.0.1 8080 <<EOF | awk 'NR==1{if ($2 == "500") exit 0; exit 1;}'; then
GET / HTTP/1.1
Host: www.example.com

EOF

    Apache2ctl restart;
fi
9
marco

Pour suivre les redirections 3XX et imprimer les codes de réponse pour toutes les demandes:

HTTP_STATUS="$(curl -IL --silent example.com | grep HTTP )";    
echo "${HTTP_STATUS}";
8
siliconrockstar

Une autre variante:

       status=$(curl -sS  -I https://www.healthdata.gov/user/login  2> /dev/null | head -n 1 | cut -d' ' -f2)
status_w_desc=$(curl -sS  -I https://www.healthdata.gov/user/login  2> /dev/null | head -n 1 | cut -d' ' -f2-)
2
dkinzer

Voici le long script - pourtant facile à comprendre -, inspiré de la solution nicerobot , qui ne demande que les en-têtes de réponse et évite d’utiliser IFS comme suggéré ici . Il renvoie un message de renvoi lorsqu'il rencontre une réponse> = 400. Cet écho peut être remplacé par un script de renvoi.

# set the url to probe
url='http://localhost:8080'
# use curl to request headers (return sensitive default on timeout: "timeout 500"). Parse the result into an array (avoid settings IFS, instead use read)
read -ra result <<< $(curl -Is --connect-timeout 5 "${url}" || echo "timeout 500")
# status code is second element of array "result"
status=${result[1]}
# if status code is greater than or equal to 400, then output a bounce message (replace this with any bounce script you like)
[ $status -ge 400  ] && echo "bounce at $url with status $status"
2
Thomas Praxl

cela peut aider à évaluer le statut http

var=`curl -I http://www.example.org 2>/dev/null | head -n 1 | awk -F" " '{print $2}'`
echo http:$var
1
Tango

Pour ajouter au commentaire @DennisWilliamson ci-dessus:

@VaibhavBajpai: essayez ceci: response = $ (curl --write-out\n% {http_code} --silent --output - nom_serveur) - la dernière ligne du résultat sera le code de réponse.

Vous pouvez ensuite analyser le code de réponse de la réponse en utilisant quelque chose de similaire au suivant, où X peut signifier une regex pour marquer la fin de la réponse (en utilisant un exemple json ici)

X='*\}'
code=$(echo ${response##$X})

Voir Suppression de sous-chaîne: http://tldp.org/LDP/abs/html/string-manipulation.html

0
user1015492