Wird der HTTP-Statuscode von Curl ausgegeben?

800

Ich benutze curlan der Befehlszeile unter Linux, um HTTP-Anforderungen auszugeben. Die Antwortkörper werden auf Standardausdruck gedruckt, was in Ordnung ist, aber auf der Manpage kann ich nicht nachvollziehen, wie der HTTP-Statuscode aus der Antwort (404, 403 usw.) gedruckt werden kann. Ist das möglich?

kdt
quelle
Was mich betrifft, kann ich dem Handbuch entnehmen, wie man den HTTP-Statuscode erhält, aber die Option -w funktioniert nicht. Ich habe Apple den Fehler gemeldet.
Nicolas Barbulesco
19
Die -iFlagge, wie in curl -i https://www.example.com/, ist wahrscheinlich das, was Sie wollen, wie pro superuser.com/a/514798/190188
caw
Warum nicht einfach so curl -IL http://www.example.com | grep "^HTTP\/"?
St3an
Nicht für zukünftige Selbst: Die Antwort, die Sie wollen, ist wahrscheinlich Cyril Davids (derzeit auf Position 4)
WhiteHotLoveTiger

Antworten:

526

Dies sollte für Sie funktionieren, wenn der Webserver in der Lage ist, auf HEAD-Anfragen zu antworten (dies führt keine aus GET):

curl -I http://www.example.org

Damit cURL Redirects (3xx-Status) folgen kann, muss zusätzlich -L hinzugefügt werden.

pberlijn
quelle
155
NB: curl -Iführt eine HEAD-HTTP-Anforderung durch, die zum Testen des HTTP-Statuscodes für einige Webanwendungsserver und -dienste problematisch sein kann
Jay Taylor,
16
Und um nur die head -n 1|cut -d$' ' -f2
Statusnummer
33
Vergessen Sie nicht , Curls stderr zu umleiten: curl -I http://www.example.org 2>/dev/null | head -n 1 | cut -d$' ' -f2. Fügen Sie -L zum Einrollen hinzu, wenn Sie den endgültigen Status nach Umleitungen benötigen.
Aaron Blenkush
1
Das Verfolgen der Umleitung nach nur einer HEAD-Anforderung kann abhängig von der Programmierung der App zu einem interessanten Verhalten führen.
Scott McIntyre
31
curl -I -X GETsendet eine GET-Anfrage, gibt aber die gleiche Ausgabe aus.
jiggy
835

Eine spezifischere Methode, um nur den HTTP-Statuscode auszudrucken, sieht folgendermaßen aus:

curl -s -o /dev/null -w "%{http_code}" http://www.example.org/

Es ist viel einfacher, mit Skripten zu arbeiten, da keine Analyse erforderlich ist :-)

Der Parameter -Ikann hinzugefügt werden, um die Leistung beim Laden der Antwort zu verbessern. Dieser Parameter fordert nur Status / Header der Antwort an, ohne den Antworttext herunterzuladen.

Hinweis: %{http_code} Gibt die erste Zeile der HTTP-Nutzdaten zurück

dh:

curl -s -o /dev/null -I -w "%{http_code}" http://www.example.org/
pvandenberk
quelle
54
-w "% {http_code}" ist das Bit, das den Statuscode ausgibt. Sie können ein oder zwei Zeilen einfügen, um den Code vom Hauptteil zu trennen (-w "\ n \ n% {http_code} \ n")
Jeffrey Martinez
7
Wow, dieses /dev/nullDing funktioniert sogar in der Windows-Version von Curl, die ich verwende.
Uwe Keim
3
Ich glaube, dies lädt die gesamte Datei herunter, obwohl alles in / dev / null gespeichert ist. Daher ist dies nicht ideal, um den Statuscode auf große Dateien zu überprüfen. httping -c 1 -s -G -mgibt ein GET aus und lädt nicht die gesamte Datei herunter, obwohl mir klar ist, dass es bei dieser Frage speziell um Locken geht.
RomanSt
40
Zu Ihrer Information: -s= Download-Fortschritt -o /dev/nullnicht anzeigen, -w "%{http_code}"= Body nicht anzeigen, = HTTP-Antwortcode nach dem Beenden an stdout schreiben.
Ajedi32
1
Sind die Anführungszeichen um den "% {http_code}" erforderlich?
Hakan Baba
217

Wenn Sie sowohl die Überschrift als auch das Ergebnis sehen möchten, können Sie die ausführliche Option verwenden:

curl -v http://www.example.org
curl --verbose http://www.example.org

Der Status wird in der Kopfzeile angezeigt. Z.B

< Date: Tue, 04 Nov 2014 19:12:59 GMT
< Content-Type: application/json; charset=utf-8
< Status: 422 Unprocessable Entity
Enrico Susatyo
quelle
26
+1 für das Hervorheben des ausführlichen Flags liefert die zusätzlichen Details. Ideal zum Testen von REST-Apps.
MrOodles
8
+1 sehr einfach zu verwenden, wenn POST-Anforderung (curl -v - Daten "...")
MegaTux
1
Es teilt sie sogar in zwei verschiedene Dateiausgaben auf (http-Statusdetails zu stderr und Antworttext zu stdout)
Blauhirn
201

Sie können den Statuscode zusätzlich zu allen Kopfzeilen wie folgt drucken:

curl -i http://example.org

Das Gute daran -iist, dass es auch funktioniert -X POST.

Cyril David
quelle
36
Viel besser als die akzeptierte Antwort (die eine HEAD-Anfrage macht).
Neu242
10
Vielleicht offensichtlich, aber -ies funktioniert mit jeder HTTP-Methode, nicht nur GETund POST... :)
Mac
3
Die beste Antwort ist die Ausgabe von Kopf- und Textzeilen, sodass die meisten Aufgaben in einem Skript ausgeführt werden können
Sarge Borsch,
6
Dies ist die beste Antwort und kann in Verbindung mit -s(Fortschrittsanzeige oder Fehlermeldungen nicht anzeigen) und -S(Fehlermeldungen immerhin
Jonathan Hartley
69

Wenn Sie den HTTP-Statuscode in einer Variablen erfassen und dennoch den Inhalt an STDOUT umleiten möchten, müssen Sie zwei STDOUTs erstellen. Dies können Sie mit process substitution> () und command substitution $ () tun .

Erstellen Sie zunächst einen Dateideskriptor 3für den aktuellen Prozess 'STDOUT mit exec 3>&1.

Dann die Nutzung curl -oOption , um den Antwortinhaltes in einen temporären Fifo mit dem Befehl Substitution und dann innerhalb dieses Befehls Substitution, umleiten Ausgabe zurück zu Ihrem aktuellen Prozess STDOUT Dateideskriptors zu umleiten 3mit -o >(cat >&3).

Alles zusammen bash 3.2.57(1)-release(Standard für macOS):

# creates a new file descriptor 3 that redirects to 1 (STDOUT)
exec 3>&1 
# Run curl in a separate command, capturing output of -w "%{http_code}" into HTTP_STATUS
# and sending the content to this command's STDOUT with -o >(cat >&3)
HTTP_STATUS=$(curl -w "%{http_code}" -o >(cat >&3) 'http://example.com')

Beachten Sie, dass dies nicht funktioniert, /bin/shwie in den Kommentaren unten angegeben .

Heidegrenzen
quelle
5
Das ist echt knifflig ... und ich mag es!
Spyle
3
Wie kann ich nun die Ausgabe in eine andere Variable umleiten?
Roger Filmyer
1
Die Ausgabe ist in STDOUT, daher sollten Sie in der Lage sein, die Ausgabe des Befehls wie bei einem normalen Befehl an eine beliebige Stelle umzuleiten. Ich habe das aber nicht getestet.
Heath Borders
1
Funktioniert nicht mit / bin / sh.
SamK
gute antwort, sie können auch zu einer echten datei umleiten und sie später katzen, wenn sie portabilität von shells wollen
akostadinov
32

Curl-Ausgabe neu definieren:

curl -sw '%{http_code}' http://example.org

Kann mit jedem Anfragetyp verwendet werden.

Grzegorz Luczywo
quelle
-k (--insecure) überschreibt -s (silent).
Ravichandra
16

NUR Statuscode

[0]$ curl -LI http://www.example.org -o /dev/null -w '%{http_code}\n' -s
[0]$ 200

Alles Verdienst dieser GIST

mahatmanich
quelle
11

Dies ist eine schmerzhafte curl --failEinschränkung. Von man curl:

-f, --fail (HTTP) Schlägt bei Serverfehlern im Hintergrund fehl (überhaupt keine Ausgabe)

Aber es gibt keinen Weg , um sowohl den Nicht-Null - Return - Code zu erhalten und den Antworttext in stdout.

Basierend auf der Antwort von pvandenberk und diesem anderen sehr nützlichen Trick, der auf SO gelernt wurde , ist hier eine Problemumgehung:

curl_with_error_code () {
    _curl_with_error_code "$@" | sed '$d'
}
_curl_with_error_code () {
    local curl_error_code http_code
    exec 17>&1
    http_code=$(curl --write-out '\n%{http_code}\n' "$@" | tee /dev/fd/17 | tail -n 1)
    curl_error_code=$?
    exec 17>&-
    if [ $curl_error_code -ne 0 ]; then
        return $curl_error_code
    fi
    if [ $http_code -ge 400 ] && [ $http_code -lt 600 ]; then
        echo "HTTP $http_code" >&2
        return 127
    fi
}

Diese Funktion verhält sich genau so curl, gibt jedoch curlbei einem HTTP-Code im Bereich [400, 600 [ 127 zurück (ein von nicht verwendeter Rückkehrcode ).

Lucas Cimon
quelle
Einverstanden, die Fehlerausgabe nicht sehen zu können, ist eine schmerzhafte Einschränkung des ansonsten sehr handlichen - Versagens. Wie können Sie einen REST-API-Fehler diagnostizieren, ohne die Fehlerausgabe zu sehen? Es ist so bedauerlich, dass der Curl-Betreuer hartnäckig darauf besteht, keinen --fail-but-show-error anzugeben. github.com/curl/curl/issues/1978
jamshid
Wie in der Dokumentation angegeben, funktioniert es nicht für 401 und 407 HTTP-Code :(
Logan Mzz
11

Dadurch wird eine Anfrage an die URL gesendet, nur die erste Zeile der Antwort abgerufen, auf Blöcke aufgeteilt und die zweite ausgewählt.

Es enthält den Antwortcode

curl -I http://example.org 2>/dev/null | head -n 1 | cut -d$' ' -f2
Filip Spiridonov
quelle
1
Können Sie erklären, was dieser Code bewirkt und wie er das vom OP angegebene Problem behebt? Unerklärlicher Code kann für Benutzer als nicht vertrauenswürdig und gefährlich erscheinen.
bwDraco
1
Sicher, wir senden eine Anfrage an url, rufen nur die erste Zeile der Antwort ab, teilen sie in Blöcke auf und wählen die zweite aus. Es enthält den Antwortcode, nach dem OP sucht.
Filip Spiridonov
9

Bei einer POST-Anfrage hat Folgendes funktioniert:

curl -w 'RESP_CODE:%{response_code}' -s -X POST --data '{"asda":"asd"}' http://example.com --header "Content-Type:application/json"|grep -o  'RESP_CODE:[1-4][0-9][0-9]'
zafar142003
quelle
6

Verwenden Sie den folgenden cURL-Befehl und leiten Sie ihn an grep weiter:

$ curl -I -s -L http://example.com/v3/get_list | grep "HTTP / 1.1"

Hier ist, was jede Flagge tut:

  • -I: Nur Antwortheader anzeigen
  • -s: Lautlos - Fortschrittsbalken nicht anzeigen
  • -L: Location:Kopfzeilen folgen

Hier ist ein Link zu HTTP-Statuscodes .

Führen Sie von der Befehlszeile aus. Diese Locke wird im unbeaufsichtigten Modus ausgeführt, folgt allen Weiterleitungen und ruft die HTTP-Header ab. grep gibt den HTTP-Statuscode in der Standardausgabe aus.

Savitoj Singh
quelle
5
curl -so -i /dev/null -w "%{http_code}"  http://www.any_example.com

Dies gibt die folgenden Informationen zurück:

  1. Antwortdaten, wenn Daten wie ein Fehler von der API zurückgegeben werden
  2. Statuscode
Srana
quelle
Dies folgt keinen Weiterleitungen. Diese bestehende Antwort ist besser superuser.com/a/442395/475508
cricket_007
Klar, das kannst du auch verweisen !!
Srana
4

Hier ist ein Curl-Befehl, der GETden HTTP-Code zurückgibt.

curl -so /dev/null -w '%{response_code}' http://www.example.org

Bitte denken Sie daran, dass der unten beschriebene Ansatz HEADzwar schneller ist, aber bei einigen Web-weniger kompatiblen HTTP-Servern möglicherweise nicht funktioniert.

 curl -I http://www.example.org
Sorin
quelle
Funktioniert zumindest nicht unter OS X.
Ain
Funktioniert gut für mich unter OS X High Sierra 10.13.6.
Ben Baron
4

Ein Beispiel für die Verwendung der Antwortcodes. Ich verwende dies, um Geolite-Datenbanken nur dann erneut herunterzuladen, wenn sie sich geändert haben ( -z) und auch folgende Weiterleitungen ( -L):

url=http://example.com/file.gz
file=$(basename $url)

response=$(curl -L -s -o $file -z $file $url -w "%{http_code}")

case "$response" in
        200) do_something ;;
        301) do_something ;;
        304) printf "Received: HTTP $response (file unchanged) ==> $url\n" ;;
        404) printf "Received: HTTP $response (file not found) ==> $url\n" ;;
          *) printf "Received: HTTP $response ==> $url\n" ;;
esac
Stuart Cardall
quelle
3

Das OP möchte den Statuscode wissen. Wenn Sie eine Datei herunterladen, möchten Sie häufig auch ein Gefühl für deren Größe bekommen. Daher verwende ich curl zuerst, um den Statuscode und die Größe der Datei anzuzeigen, und schalte dann die ausführliche und direkte Datei an den gewünschten Ort und Namen aus:

curl -R -s -S -w  "\nhttp: %{http_code} %{size_download}\n" -o /Users/myfiles/the_local_name.html http://archive.onweb.com/the_online_name.html

Dann warte ich auf das Ende der Locke

wait ${!}

bevor ich den nächsten Befehl ausführen. Das Obige gibt, wenn es in einem Skript mit vielen Befehlen wie oben verwendet wird, eine nette Antwort wie:

http: 200 42824

http: 200 34728

http: 200 35452

Bitte beachten Sie, dass hinter -o in curl der vollständige Pfad der Datei + der Dateiname stehen muss. Auf diese Weise können Sie Dateien in einer sinnvollen Namensstruktur speichern, wenn Sie sie mit Curl d / l. Beachten Sie auch, dass -s und -S zusammen die Ausgabe zum Schweigen bringen, aber Fehler anzeigen. Beachten Sie auch, dass -R versucht, den Zeitstempel der Datei auf den der Webdatei zu setzen.

Meine Antwort basiert auf dem, was @pvandenberk ursprünglich vorgeschlagen hat, aber zusätzlich speichert es die Datei tatsächlich irgendwo, anstatt nur nach / dev / null zu leiten.

Sakumatto
quelle
1

Teilen Sie den Ausgabeinhalt auf stdoutund den HTTP-Statuscode auf stderr:

curl http://www.example.org -o >(cat >&1) -w "%{http_code}\n" 1>&2

Wenn nur der HTTP-Statuscode stderr sein soll, --silentkann Folgendes verwendet werden:

curl --silent http://www.example.org -o >(cat >&1) -w "%{http_code}\n" 1>&2

Der gewünschte Stream kann dann ausgewählt werden, indem unerwünschter Stream weitergeleitet wird an /dev/null:

$ (curl --silent http://www.example.org -o >(cat >&1) -w "%{http_code}" 1>&2) 1>/dev/null
200
$ (curl --silent http://www.example.org -o >(cat >&1) -w "%{http_code}" 1>&2) 2>/dev/null
<!doctype html>
...

Beachten Sie, dass Sie den Befehl curl in der Subshell ausführen müssen, damit sich die zweite Umleitung wie gewünscht verhält.

Jaakko
quelle
1
Erfordert basheine Prozessersetzung.
Jaakko
@Bruno, änderte ich das Beispiel von superuser.com/revisions/1444693/2 , wie ich die denken , /tmp/out /tmp/errDateien zu unerwarteten Ergebnissen führen kann , wenn parallel laufen.
Jaakko vor