Kann ich dafür sorgen, dass cURL mit einem anderen exitCode als 0 fehlschlägt, wenn der HTTP-Statuscode nicht 200 ist?

239

Ich bin immer davon ausgegangen, dass curl bei einer HTTP 500-Antwort einen Exit-Code zurückgibt, der einen Fehler bedeutet (! = 0), aber das scheint nicht der Fall zu sein.

Gibt es eine Möglichkeit, cURL mit einem anderen exitCode als 0 zum Scheitern zu bringen, wenn der HTTP-Statuscode nicht 200 ist? Ich weiß, dass ich es verwenden kann, -w "%{http_code}"aber das bringt es in STDOUT, nicht als Exit-Code (außerdem bin ich auch daran interessiert, die Ausgabe zu erfassen, die ich nicht in eine Datei, sondern auf den Bildschirm umleiten möchte).

wissen
quelle

Antworten:

263

curl --fail macht einen Teil von dem, was Sie wollen:

von man curl:

-f, --fail

(HTTP) Schlägt bei Serverfehlern im Hintergrund fehl (überhaupt keine Ausgabe). Dies geschieht hauptsächlich, um Skripte usw. besser zu aktivieren und fehlgeschlagene Versuche besser zu verarbeiten. In normalen Fällen gibt ein HTTP-Server, der ein Dokument nicht zustellt, ein HTML-Dokument zurück, in dem dies angegeben ist (in dem häufig auch das Warum und mehr beschrieben wird). Dieses Flag verhindert, dass Curl dies ausgibt, und gibt den Fehler 22 zurück.

Diese Methode ist nicht ausfallsicher und es gibt Situationen, in denen nicht erfolgreiche Antwortcodes durchschlagen, insbesondere wenn es sich um eine Authentifizierung handelt (Antwortcodes 401 und 407).

Aber es blockiert die Ausgabe auf dem Bildschirm.

Rampion
quelle
2
Also, welche Teile davon tun es und welche nicht?
Rogerdpack
5
@rogerdpack tl; dr es gibt nicht null zurück, wenn es eine schlechte Antwort erkennt, aber es würde OP nicht
erlauben
3
HTTP 301 Move wird dadurch nicht dauerhaft abgefangen. Curl gab noch Exit-Code 0.
wisbucky
4
@wisbucky 301 ist kein Fehler, sondern ein Umleitungsstatuscode. Fehler sind 4xx und 5xx Statuscodes.
M. Justin
1
@wisbucky verlassen ungleich Null auf HTTP - Fehlercodes und HTTP behandeln Umleitungen richtig verwenden curl -f -Lund sehen diese Frage für Details auf , was der -LFall ist.
Noah Sussman
81

Wenn Sie nur den Inhalt der gewellten Seite anzeigen möchten, können Sie dies tun:

STATUSCODE=$(curl --silent --output /dev/stderr --write-out "%{http_code}" URL)

if test $STATUSCODE -ne 200; then
    # error handling
fi

Dadurch wird der Inhalt der Seite in STDERR geschrieben, während der HTTP-Statuscode in STDOUT geschrieben wird, sodass er der Variablen STATUSCODE zugewiesen werden kann .

Dennis
quelle
3
Wie wäre es, wenn ich die Antwort bei einem Fehler ausgeben möchte (nicht 200) , aber einen Nicht- 0Statuscode aus dem Skript zurückgeben möchte ?
Justin
2
@Justin: Was ist mit if [ "$statuscode" -ne 200 ]; then exit "$statuscode"; fi?
ghoti
4
@ghoti: Es werden nur 8-Bit-Exit-Codes ohne Vorzeichen unterstützt, was etwas verwirrend sein kann.
Dennis
3
Ah, richtig - und Codes werden mit 8 Bits umgebrochen, so dass Fehler 404 den Ausgangswert 148, 500 den Wert 244 annimmt. In der Tat verwirrend! :-)
ghoti
7
Als kleine Variation wird der Code in einer Variablen erfasst, während die Antwort auf stdout und nicht auf stderr umgeleitet wird : { code=$(curl ... as above ...); } 2>&1Der Trick ist { ... } 2>&1, dass das Umleiten möglich ist, ohne eine andere Shell zu ( ... )erzeugen.
Tobia
31

Ich konnte es mit einer Kombination von Flags machen:

curl --silent --show-error --fail URL

--silent verbirgt den Fortschritt und den Fehler.
--show-error zeigt die von --silent
--fail ausgeblendete Fehlermeldung an , die einen Exit-Code> 0 zurückgibt, wenn die Anfrage fehlschlägt

Ricardo Souza
quelle
5
Dies zeigt keine Serverantwort. Ich bin nicht in Betrieb, aber ich vermute, er wollte eine Fehlermeldung vom Server sehen, die im Body zurückgegeben wird. Ansonsten --silent --show-error --failfunktioniert das genauso wie eben -f/--fail.
Verschwenden Sie den
1
Eigentlich --failgibt Exit - Code 22, wie dokumentiert .
Quolonel Fragen
2
@wisbucky 301 ist kein Fehler, sondern ein Umleitungsstatuscode. Fehler sind 4xx und 5xx Statuscodes.
M. Justin
4
Um fair zu @wisbucky zu sein, lautet die ursprüngliche Frage "[...] wenn der HTTP-Statuscode nicht 200 ist" . Nirgendwo zuvor wurde von "Fehler" gesprochen.
Ken
2
@ M.Justin Laut Curl-Manpage: Diese Methode ist nicht ausfallsicher und es gibt Situationen, in denen nicht erfolgreiche Antwortcodes durchschlagen, insbesondere wenn es um die Authentifizierung geht (Antwortcodes 401 und 407).
Sie
0

Ja, es gibt eine Möglichkeit, dies zu tun, aber dies ist alles andere als offensichtlich, da es sich um drei Optionen handelt:

curl -s --fail --show-error https://httpbin.org/status/200 > /dev/null
curl -s --fail --show-error https://httpbin.org/status/401 > /dev/null
curl -s --fail --show-error https://httpbin.org/status/404 > /dev/null
curl -s --fail --show-error https://bleah-some-wrong-host > /dev/null

Dies stellt sicher, dass Erfolg (0) nur dann eintritt, wenn curl uns den endgültigen 2xxRückkehrcode gibt und stdoutder Body abgerufen wird und alle Fehler stderr angezeigt werden.

Bitte beachten Sie, dass die Curl-Dokumentation Sie ein wenig verwirren kann, da erwähnt wird, dass --fail bei einigen 401-Codes erfolgreich sein kann. Basierend auf Tests ist das nicht wahr, zumindest nicht bei gleichzeitiger Verwendung mit --show-error.

Bisher konnte ich keinen Fall finden, in dem Curl erfolgreich war, wenn es mit diesen Optionen nicht erfolgreich war.

Sorin
quelle
1
ist das im Wesentlichen die gleiche Antwort wie die von Ricardo Souza?
Knocte