wake-up-neo.com

Wie kann man HTTP-Antwortcodes aus dem Bash / Shell-Skript auswerten?

Ich habe das Gefühl, dass ich das Offensichtliche vermisse, aber es ist mir nicht gelungen mit man [curl|wget] oder google ("http" macht einen so schlechten Suchbegriff). Ich suche nach einer schnellen und fehlerhaften Lösung für einen unserer Webserver, die häufig ausfällt und den Statuscode 500 mit einer Fehlermeldung zurückgibt. Sobald dies passiert ist, muss es neu gestartet werden.

Da die Ursache schwer zu finden zu sein scheint, streben wir eine schnelle Lösung an, in der Hoffnung, dass es ausreicht, die Zeit zu überbrücken, bis wir sie wirklich beheben können (für den Service ist keine hohe Verfügbarkeit erforderlich).

Die vorgeschlagene Lösung besteht darin, einen Cron-Job zu erstellen, der alle 5 Minuten ausgeführt wird. Aktivieren Sie dabei http: // localhost: 8080 / . Wenn dies mit dem Statuscode 500 zurückgegeben wird, wird der Webserver neu gestartet. Der Server wird in weniger als einer Minute neu gestartet, sodass nicht überprüft werden muss, ob bereits Neustarts ausgeführt werden.

Bei dem fraglichen Server handelt es sich um eine Ubuntu 8.04-Minimalinstallation, bei der nur genügend Pakete installiert sind, um das auszuführen, was derzeit benötigt wird. Es ist nicht schwierig, die Aufgabe in Bash auszuführen, aber ich möchte, dass sie in einer so minimalen Umgebung ausgeführt wird, ohne dass weitere Interpreter installiert werden.

(Ich bin mit Skripten hinreichend vertraut, sodass der Befehl/die Optionen zum Zuweisen des http-Statuscodes zu einer Umgebungsvariablen ausreichen - das habe ich gesucht und nicht gefunden.)

173
Olaf Kock

Ich habe dies nicht mit einem 500er Code getestet, aber es funktioniert mit anderen wie 200, 302 und 404.

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

Fügen Sie, wie von @ibai vorgeschlagen, --head Hinzu, um nur eine HEAD) - Anforderung zu stellen. Dies spart Zeit, wenn der Abruf erfolgreich ist, da der Seiteninhalt nicht übertragen wird.

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

funktioniert. Wenn nicht, müssen Sie die Eingabetaste drücken, um den Code selbst anzuzeigen.

38
hd1

Obwohl akzeptierte Antwort eine gute Antwort ist, werden Fehlerszenarien übersehen. curl gibt 000 zurück, wenn ein Fehler in der Anforderung oder ein Verbindungsfehler vorliegt.

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

Hinweis: Dies geht ein wenig über die angeforderte Statusprüfung 500 Hinaus, um zu bestätigen, dass curl sogar eine Verbindung zum Server herstellen kann (d. H. 000 Zurückgibt).

Erstellen Sie daraus eine Funktion:

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 ]]
}

Testen Sie, wie Sie einen 500 Erhalten:

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

Test abrufen Fehler/Verbindungsfehler (d. H. 000):

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

Test nicht bekommen einen 500:

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

Ich musste heute schnell etwas vorführen und kam auf diese Idee. Ich dachte, ich würde es hier platzieren, wenn jemand etwas Ähnliches wie die OP-Anfrage benötigt.

#!/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

Dadurch wird bei jeder Statusänderung von 200 eine E-Mail-Benachrichtigung gesendet, die dumm und potenziell gierig ist. Um dies zu verbessern, würde ich mehrere Statuscodes durchlaufen und abhängig vom Ergebnis verschiedene Aktionen ausführen.

17
Chris Gillatt

Mit netcat und awk können Sie die Serverantwort manuell behandeln:

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

So folgen Sie 3XX-Weiterleitungen und drucken Antwortcodes für alle Anforderungen:

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

Eine andere 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

Hier kommt das langwierige und dennoch leicht verständliche Skript, das von der Lösung von nicerobot inspiriert ist und nur die Antwortheader anfordert und die vorgeschlagene Verwendung von IFS vermeidet hier . Es gibt eine Bounce-Nachricht aus, wenn es auf eine Antwort> = 400 stößt. Dieses Echo kann durch ein Bounce-Skript ersetzt werden.

# 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

dies kann bei der Bewertung des http-Status hilfreich sein

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

So fügen Sie oben einen Kommentar zu @DennisWilliamson hinzu:

@VaibhavBajpai: Versuchen Sie Folgendes: response = $ (curl --write-out\n% {http_code} --silent --output - servername) - die letzte Zeile im Ergebnis ist der Antwortcode

Sie können dann den Antwortcode aus der Antwort mit der folgenden Methode analysieren, wobei X einen regulären Ausdruck zum Markieren des Endes der Antwort bedeuten kann (hier anhand eines JSON-Beispiels).

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

Siehe Entfernen der Teilzeichenfolge: http://tldp.org/LDP/abs/html/string-manipulation.html

0
user1015492