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é.)
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.
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.
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
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.
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
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}";
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-)
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"
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
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