Puis-je faire échouer cURL avec un exitCode différent de 0 si le code d'état HTTP n'est pas 200?

239

Je suis toujours en supposant que lorsque boucle a une réponse HTTP 500 , il retournait un code de sortie qui signifiait l' échec (! = 0), mais qui semble être pas le cas.

Existe-t-il un moyen de faire échouer cURL avec un exitCode différent de 0 si le code d'état HTTP n'est pas 200? Je sais que je peux l'utiliser -w "%{http_code}"mais cela le met dans STDOUT, non pas comme code de sortie (en outre, je suis également intéressé par la capture de la sortie, que je ne veux pas rediriger vers un fichier, mais vers l'écran).

knocte
la source

Réponses:

264

curl --fail fait partie de ce que vous voulez:

de man curl:

-f, --fail

(HTTP) Échec silencieux (pas de sortie du tout) sur les erreurs de serveur. Ceci est principalement fait pour permettre aux scripts, etc. de mieux gérer les tentatives infructueuses. Dans les cas normaux, lorsqu'un serveur HTTP ne parvient pas à livrer un document, il renvoie un document HTML le déclarant (qui décrit souvent également pourquoi et plus). Cet indicateur empêchera curl de sortir cela et renverra l'erreur 22.

Cette méthode n'est pas sécurisée et il peut arriver que des codes de réponse infructueux glissent, en particulier lorsque l'authentification est impliquée (codes de réponse 401 et 407).

Mais cela bloque la sortie à l'écran.

rampion
la source
2
Alors, quelles parties fait-il et ne fait-il pas?
rogerdpack
5
@rogerdpack tl; dr retourne une valeur différente de zéro quand il détecte une mauvaise réponse, mais ne laisse pas l'OP capturer la réponse
jeudi
3
Cela ne prend pas HTTP 301 Move en permanence. curl a toujours donné le code de sortie 0.
wisbucky
4
@wisbucky 301 n'est pas une erreur, c'est un code d'état de redirection. Les erreurs sont des codes de statut 4xx et 5xx.
M. Justin
1
@wisbucky pour sortir sur les codes non nulle erreur HTTP et gérer correctement les redirections HTTP utiliser curl -f -Let de voir cette question pour plus de détails sur ce -Lfait.
Noah Sussman le
81

Si vous souhaitez simplement afficher le contenu de la page courbée, procédez comme suit:

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

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

Ceci écrit le contenu de la page dans STDERR lors de l'écriture du code d'état HTTP dans STDOUT, afin qu'il puisse être affecté à la variable STATUSCODE .

Dennis
la source
3
Que diriez-vous si je veux sortir la réponse en cas d'échec (non 200) , mais renvoyer un 0code non d' état à partir du script?
Justin
2
@Justin: Qu'en est-il if [ "$statuscode" -ne 200 ]; then exit "$statuscode"; fi?
Ghoti
4
@ ghoti: Seuls les codes de sortie 8 bits non signés sont pris en charge, ce qui peut prêter à confusion.
Dennis
3
Ah, oui - et les codes seront bouclés à 8 bits, ainsi l'erreur 404 devient la valeur de sortie 148, 500 devient 244. Confondant en effet! :-)
ghoti
7
En légère variation, cela capture le code dans une variable tout en redirigeant la réponse vers stdout, pas stderr: { code=$(curl ... as above ...); } 2>&1le truc, c'est { ... } 2>&1que cela permet de rediriger tout en ne créant pas un shell différent ( ... ).
Tobia
31

J'ai été capable de le faire en utilisant une combinaison de drapeaux:

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

--silent masque la progression et l'erreur
--show-error affiche le message d'erreur masqué par --silent
--fail renvoie un code de sortie> 0 lorsque la demande échoue

Ricardo Souza
la source
5
Cela ne montre pas la réponse du serveur. Je ne suis pas op mais je soupçonne qu'il voulait voir n'importe quel message d'erreur du serveur qui est retourné dans le corps. En plus, ça --silent --show-error --failmarche pareil que juste -f/--fail.
déchets
1
En fait, --failrenvoie le code de sortie 22, comme documenté .
Questions Quolonel
2
@wisbucky 301 n'est pas une erreur, c'est un code d'état de redirection. Les erreurs sont des codes de statut 4xx et 5xx.
M. Justin
4
Pour être juste envers @ wisbucky, la question initiale disait "[...] si le code de statut HTTP n'est pas 200" . Aucune mention "d'erreur" n'importe où avant.
Ken
2
@ M.Justin Selon la page de manuel curl: Cette méthode n’est pas sécurisée et il peut arriver que des codes de réponse infructueux glissent, notamment en cas d’authentification (codes de réponse 401 et 407).
Youfu
0

Oui, il y a un moyen de le faire mais c'est loin d'être évident car cela implique 3 options:

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

Cela garantit que le succès (0) ne se produit que lorsque curl se termine avec le 2xxcode de retour final , qui stdoutobtient le corps et que les erreurs éventuelles sont affichées dans stderr.

Veuillez noter que la documentation de curl peut vous confondre un peu car elle mentionne que --fail pourrait réussir pour quelque 401 codes. Basé sur des tests, ce n'est pas vrai, du moins pas lorsqu'il est utilisé avec --show-error en même temps.

Jusqu'à présent, je n'ai pu trouver aucun cas où curl renverrait le succès alors que ce n'était pas un http-succeds avec ces options.

sorin
la source
1
Est-ce essentiellement la même réponse que celle de Ricardo Souza?
knocte