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

j'ai le sentiment que je manque l'évidence, mais je n'ai pas réussi avec man [curl|wget] ou google ("http" rend un terme de recherche Si mauvais). Je suis à la recherche d'une solution rapide et sale à l'un de nos serveurs Web qui échoue souvent, en retournant le code d'État 500 avec un message d'erreur. Une fois que cela se produit, il faut le redémarrer.

Comme la cause semble être difficile à trouver, nous visons une solution rapide, en espérant que cela sera suffisant pour combler le temps jusqu'à ce que nous pouvons really fix it (le service n'a pas besoin d'une grande disponibilité)

la solution proposée est de créer une tâche cron qui court toutes les 5 minutes, en cochant http://localhost:8080 / . Si cela retourne avec le code d'État 500, le serveur web sera redémarré. Le serveur va redémarrer en moins d'une minute, il n'est donc pas nécessaire de vérifier si les redémarrages sont déjà en cours.

le serveur en question est une installation minimale ubuntu 8.04 avec juste assez paquets installés pour exécuter ce dont il a besoin. Il n'y a pas d'exigence difficile pour faire la tâche à bash, mais je voudrais qu'elle se déroule dans un tel environnement minimal sans installer plus d'interprètes.

(je suis suffisamment familiarisé avec les scripts pour que la commande/les options pour assigner le code de statut http à une variable d'environnement soient suffisantes - c'est ce que j'ai cherché et que je n'ai pas pu trouver.)

151
demandé sur Olaf Kock 2010-02-08 11:25:33

10 réponses

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

response=$(curl --write-out %{http_code} --silent --output /dev/null servername)
243
répondu Dennis Williamson 2010-02-08 09:48:46
curl --write-out "%{http_code}\n" --silent --output /dev/null "$URL"

works. Si ce n'est pas le cas, vous devez appuyer sur Retour pour voir le code lui-même.

32
répondu hd1 2012-11-16 08:49:35

ici:

url='http://localhost:8080/'
status=$(r=(IFS=' ';$(curl -Is --connect-timeout 5 "${url}" || echo 1 500));echo ${r[1]})
[ status -eq 500 ] && bounce # assuming the bounce script is called 'bounce'

ou mettez tout sur une ligne:

[ 500 -eq $(r=(IFS=' ';$(curl -Is --connect-timeout 5 'http://localhost:8080/' || echo 1 500));echo ${r[1]}) ] && bounce

pour expliquer, la réponse HTTP contient toujours l'état du serveur dans le cadre de la première ligne de la réponse, comme:

HTTP/1.1 200 OK
HTTP/1.0 404 NOT FOUND

le script n'utilise que curl pour faire une requête HEAD à localhost:8080. Il convertit L'en-tête HTTP en un tableau et renvoie le second élément. Pour simplifier un peu la manipulation de la défaillance, si la tête ne se connecte pas dans les 5 secondes ou curl échoue pour une raison quelconque, 500 est également retourné.

14
répondu nicerobot 2010-02-08 14:48:50

j'avais besoin de faire une démonstration rapide aujourd'hui et j'ai trouvé ça. J'ai pensé que je le placerais ici si quelqu'un avait besoin de quelque chose similaire à la demande de L'OP.

#!/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" "my_email@email.com" -r "STATUS_CHECKER"
else
  exit 0
fi

ceci enverra un e-mail d'alerte sur chaque changement d'état de 200, donc c'est stupide et potentiellement gourmand. Pour améliorer cette situation, j'envisagerais de passer en boucle plusieurs codes de statut et d'effectuer différentes actions en fonction du résultat.

11
répondu Chris Gillatt 2017-10-24 14:56:29

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 ( == "500") exit 0; exit 1;}'; then
GET / HTTP/1.1
Host: www.example.com

EOF

    apache2ctl restart;
fi
9
répondu marco 2010-02-08 10:09:31

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
répondu siliconrockstar 2015-10-31 03:02:48

cela peut aider à évaluer le statut http

var=`curl -I http://www.example.org 2>/dev/null | head -n 1 | awk -F" " '{print }'`
echo http:$var
1
répondu Tango 2015-11-21 18:09:00

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

# 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"
1
répondu Thomas Praxl 2017-05-23 11:47:19

une autre variante:

status=$(curl -I https://www.healthdata.gov/user/login 2> /dev/null | head -n 1 | cut -d ' ' -f 2)
1
répondu dkinzer 2017-03-25 22:18:33

à ajouter au commentaire de @DennisWilliamson ci-dessus:

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

vous pouvez ensuite analyser le code de réponse à partir de la réponse en utilisant quelque chose comme ce qui suit, où X peut signifier un regex pour marquer la fin de la réponse (en utilisant un exemple de json ici)

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

voir enlèvement de substrat: http://tldp.org/LDP/abs/html/string-manipulation.html

0
répondu user1015492 2016-03-23 13:54:03