Curl, um den http-Statuscode zusammen mit der Antwort zurückzugeben

109

Ich benutze Curl, um http-Header dazu zu bringen, den http-Statuscode zu finden und auch eine Antwort zurückzugeben. Ich bekomme die http-Header mit dem Befehl

curl -I http://localhost

Um die Antwort zu erhalten, benutze ich den Befehl

curl http://localhost

Sobald ich das Flag -I benutze, bekomme ich nur die Header und die Antwort ist nicht mehr da. Gibt es eine Möglichkeit, sowohl die http-Antwort als auch den Header / http-Statuscode in einem Befehl abzurufen?

RandominstanceOfLivingThing
quelle
1
Hier ist ein sehr nützlicher Ausschnitt gist.github.com/maxcnunes/9f77afdc32df354883df
Rocketspacer

Antworten:

111

Ich konnte eine Lösung finden, indem ich mir das Curl-Dokument ansah, in dem angegeben ist, -dass die Ausgabe verwendet werden soll, um die Ausgabe auf stdout zu bringen.

curl -o - http://localhost

Um die Antwort nur mit dem http-Rückkehrcode zu erhalten, könnte ich einfach tun

curl -o /dev/null -s -w "%{http_code}\n" http://localhost
RandominstanceOfLivingThing
quelle
11
oder du würdest verwenden -i. Oder vielleicht, -vwenn Sie auch zusätzliche Informationen mögen.
Daniel Stenberg
2
Danke @DanielStenberg. Die akzeptierte Antwort hat bei mir nicht funktioniert, einfach -i hat funktioniert.
Alejandro Cotilla
Ihr zweiter Befehl fehlt -I @randominstanceOfLivingThing, es sei denn, dies ist absichtlich eine leere Option? Funktioniert nicht für mich ohne es
mdo123
2
-o -IAm Ende wird eine Datei mit dem wörtlichen Namen ' -I' im CWD erstellt. Hat das noch jemand gesehen? Die Lösung dafür ist-o/dev/null -I
JDS
-I entfernt. Ich habe es jetzt bemerkt und korrigiert. Du brauchst das -I nicht.
RandominstanceOfLivingThing
40

Der ausführliche Modus sagt Ihnen alles

curl -v http://localhost
ScotchAndSoda
quelle
36

Ich benutze diesen Befehl, um den Statuscode ohne andere Ausgabe zu drucken. Außerdem wird nur eine HEAD-Anforderung ausgeführt und die Umleitung (bzw. -Iund -L) befolgt .

curl -o -I -L -s -w "%{http_code}" http://localhost

Dies macht es sehr einfach, den Statuscode in einem Integritätsskript zu überprüfen:

sh -c '[ $(curl -o -I -L -s -w "%{http_code}" http://localhost) -eq 200 ]'
Scriptracer
quelle
5
Dies wurde bereits vor einem Jahr beantwortet. Welchen neuen Wert bringt Ihre Antwort? Bitte schreiben Sie auch eine Erklärung zu Ihrer Antwort.
Maciej Jureczko
11
@MaciejJureczko - Der Wert ist einfach. Für Skriptzwecke ist diese Antwort die beste aller anderen Antworten, da sie einen einzigen Statuscode anstelle vieler Müllzeilen zusammen mit diesem Statuscode enthält.
Aggregat1166877
2
Das OP gibt jedoch ausdrücklich an, dass sowohl der Statuscode als auch der Antworttext gewünscht werden. Sie wissen, wie man einfach den Antwortcode (in der Frage angegeben)
erhält
2
Wann immer ich dies benutze, wird curl -o -I -L -s -w "%{http_code}" http://localhosteine Datei mit dem Namen erstellt. -IUm dies zu -o/dev/nullcurl -o /dev/null -I -L -s -w "%{http_code}" http://localhost
umgehen, habe
HEAD führt jedoch nicht immer zur gleichen Ausgabe wie eine Anfrage, bis auf den Server, wie sie antworten. Das ist also keine wirkliche Antwort.
Eddie
28

Ich habe diese Frage gefunden, weil ich sowohl die Antwort als auch den Inhalt haben wollte, um dem Benutzer eine Fehlerbehandlung hinzuzufügen.

Sie können den HTTP-Statuscode drucken, um den Inhalt zu standardisieren und in eine andere Datei zu schreiben.

curl -s -o response.txt -w "%{http_code}" http://example.com

Auf diese Weise können Sie mithilfe der Logik entscheiden, ob die Antwort eine Verarbeitung wert ist.

http_response=$(curl -s -o response.txt -w "%{http_code}" http://example.com)
if [ $http_response != "200" ]; then
    # handle error
else
    echo "Server returned:"
    cat response.txt    
fi
Eddie
quelle
Was ist http_code? Ich verstehe das nicht, braucht mehr Erklärung pls
Alexander Mills
oben geklärt, bezieht es sich auf den HTTP-Statuscode - developer.mozilla.org/en-US/docs/Web/HTTP/Status
Eddie
21

Die -iOption ist die, die Sie möchten:

curl -i http://localhost

-i, --include Protokoll-Header in die Ausgabe einbeziehen (H / F)

Alternativ können Sie die ausführliche Option verwenden:

curl -v http://localhost

-v, --verbose Machen Sie die Operation gesprächiger

Owen Pauling
quelle
16

Ich habe das benutzt:

    request_cmd="$(curl -i -o - --silent -X GET --header 'Accept: application/json' --header 'Authorization: _your_auth_code==' 'https://example.com')"

Um den HTTP-Status zu erhalten

    http_status=$(echo "$request_cmd" | grep HTTP |  awk '{print $2}')
    echo $http_status

Um den Antworttext zu erhalten, habe ich diesen verwendet

    output_response=$(echo "$request_cmd" | grep body)
    echo $output_response
user2720864
quelle
8

Dieser Befehl

 curl http://localhost -w ", %{http_code}"

wird den durch Kommas getrennten Körper und Status erhalten; Sie können sie teilen, um sie herauszuholen.

Sie können das Trennzeichen nach Belieben ändern.

Tech Junkie
quelle
2
guter Hinweis! Ist es möglich, vor der Ausgabe einen Statuscode hinzuzufügen?
Psychozoikum
6

Für die programmatische Verwendung verwende ich Folgendes:

curlwithcode() {
    code=0
    # Run curl in a separate command, capturing output of -w "%{http_code}" into statuscode
    # and sending the content to a file with -o >(cat >/tmp/curl_body)
    statuscode=$(curl -w "%{http_code}" \
        -o >(cat >/tmp/curl_body) \
        "$@"
    ) || code="$?"

    body="$(cat /tmp/curl_body)"
    echo "statuscode : $statuscode"
    echo "exitcode : $code"
    echo "body : $body"
}

curlwithcode https://api.github.com/users/tj

Es zeigt folgende Ausgabe:

statuscode : 200
exitcode : 0
body : {
  "login": "tj",
  "id": 25254,
  ...
}
edi9999
quelle
4

Dies ist eine Möglichkeit, den Text "UND" des Statuscodes abzurufen und ihn auf einen geeigneten JSON oder ein für Sie geeignetes Format zu formatieren. Einige mögen argumentieren, dass es die falsche Verwendung der Schreibformatoption ist, aber dies funktioniert für mich, wenn ich sowohl Text- als auch Statuscode in meinen Skripten benötige, um den Statuscode zu überprüfen und die Antworten vom Server weiterzuleiten.

curl -X GET -w "%{stderr}{\"status\": \"%{http_code}\", \"body\":\"%{stdout}\"}"  -s -o - https://github.com 2>&1

Führen Sie den obigen Code aus und Sie sollten einen JSON in diesem Format zurückerhalten:

{
"status" : <status code>,
"body" : <body of response>
}

Mit der Option -w Schreibformat können Sie, da stderr zuerst gedruckt wird, Ihre Ausgabe mit dem var http_code formatieren und den Hauptteil der Antwort in einen Wert (body) einfügen und das Einschließen mit var stdout verfolgen. Leiten Sie dann Ihre stderr-Ausgabe auf stdout um, und Sie können sowohl http_code als auch den Antworttext zu einer übersichtlichen Ausgabe kombinieren

Huy Tran
quelle
1
curl: unknown --write-out variable: 'stderr'curl: unknown --write-out variable: 'stdout'
Erhielt
Die Manpage curl.haxx.se/docs/manpage.html zeigt die verfügbare Variable. Ich bin mir nicht sicher, warum stderr von deiner Locke nicht erkannt wird. Die Locke ist auf einem MacBook. In diesem Linux-Curl-Dokument, computerhope.com/unix/curl.htm , sehe ich stderr auch nicht als Variable. Vielleicht ist dies eine Betriebssystemvariante.
Huy Tran
Das einzige Problem, das ich damit habe, ist, wenn Ihr Körper Anführungszeichen hat, z. B. wenn sein json, der Körper die json-Antwort über dem ungültigen json
theannouncer
fair genug @theannouncer, ich würde erwarten, dass sich der Entwickler entsprechend anpasst, da nicht alle Antworten Standard-JSON sind. Es gab einige Fälle, die ich aufgrund der Art der Antwort anpassen musste.
Huy Tran
1

Mein Weg, um dies zu erreichen :

Um beides zu bekommen (Header und Body), führe ich normalerweise ein curl -D- <url>wie in:

$ curl -D- http://localhost:1234/foo
HTTP/1.1 200 OK
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/json
Date: Wed, 29 Jul 2020 20:59:21 GMT

{"data":["out.csv"]}

Dadurch werden die Header ( -D) an stdout ( -) ausgegeben ( --dump-headerin man curl suchen ).

IMHO auch in diesem Zusammenhang sehr praktisch:

Ich benutze oft jq , um diese json-Daten (z. B. von einigen Rest-APIs) zu formatieren. Da jq jedoch keinen HTTP-Header erwartet, besteht der Trick darin, Header mit stderr zu drucken -D/dev/stderr. Beachten Sie, dass wir diesmal auch -sS(--silent, --show-error) verwenden, um die Fortschrittsanzeige zu unterdrücken (weil wir in eine Pipe schreiben).

$ curl -sSD/dev/stderr http://localhost:1231/foo | jq .
HTTP/1.1 200 OK
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/json
Date: Wed, 29 Jul 2020 21:08:22 GMT

{
  "data": [
    "out.csv"
  ]
}

Ich denke, dies kann auch nützlich sein, wenn Sie Header (zur schnellen Überprüfung) auf die Konsole drucken möchten, aber den Textkörper in eine Datei umleiten möchten (z. B. wenn es sich um eine Art Binärdatei handelt, um Ihr Terminal nicht durcheinander zu bringen):

$ curl -sSD/dev/stderr http://localhost:1231 > /dev/null
HTTP/1.1 200 OK
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/json
Date: Wed, 29 Jul 2020 21:20:02 GMT

Beachten Sie: Dies ist NICHT das gleiche wie curl -I <url>! As -Iführt eine HEADAnforderung und keine GETAnforderung aus (Suchen Sie nach --headin man curl . Ja: Bei den meisten HTTP-Servern führt dies zum gleichen Ergebnis. Ich kenne jedoch viele Geschäftsanwendungen, die überhaupt keine HEADAnforderung implementieren

hiddenAlpha
quelle
-2
while : ; do curl -sL -w "%{http_code} %{url_effective}\\n" http://host -o /dev/null; done
Peter
quelle
1
Warum sollten Sie dies in eine while-Schleife setzen? Bitte erweitern und erläutern Sie Ihre Antwort.
Uberhumus