492 votes

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

J'ai toujours supposé que lorsque curl obtenait une réponse HTTP 500, il retournait un code de sortie signifiant l'échec (!= 0), mais il semble que ce soit le cas. no l'affaire.

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 utiliser -w "%{http_code}" mais cela le place dans STDOUT, pas comme code de sortie (de plus, je suis également intéressé par la capture de la sortie, que je ne veux pas rediriger vers un fichier, mais vers l'écran).

0 votes

Si vous arrivez ici bien après le 2021/02/15, veuillez noter qu'un drapeau a été ajouté à curl qui fait exactement que - voir superuser.com/a/1626376/25173 en dessous. Bien sûr, assurez-vous que votre version de curl est >= 7.76.0.

0 votes

C'est 2022 maintenant, et (selon mon exemple) le dernier docker LTS de Jenkins inclut ceci.

0 votes

Quel est le rapport entre Jenkins et ma question ?

507voto

OJ. Points 16939

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

de man curl :

-f, --fail

(HTTP) Échouer silencieusement (pas de sortie du tout) en cas d'erreur du serveur. Ceci est principalement fait pour mieux permettre aux scripts etc de mieux gérer les tentatives échouées. Dans les cas normaux, lorsqu'un serveur HTTP ne parvient pas à délivrer un document, il renvoie un document HTML le déclarant (qui décrit souvent aussi pourquoi et plus). Ce drapeau empêchera curl d'afficher ce document et retournera l'erreur 22.

Cette méthode n'est pas infaillible et il arrive que des codes de réponse non réussis se glissent entre les mailles du filet, notamment en cas d'authentification (codes de réponse 401 et 407).

Mais cela bloque la sortie sur l'écran.

6 votes

Alors, quelles sont les parties qu'il fait et qu'il ne fait pas ?

11 votes

@rogerdpack tl;dr il renvoie un résultat différent de zéro lorsqu'il détecte une mauvaise réponse, mais il ne permet pas à OP de capturer la réponse.

8 votes

Cela n'attrape pas le HTTP 301 Move Permanently. curl donne toujours le code de sortie 0.

133voto

Dennis Points 46916

Si vous souhaitez simplement afficher le contenu de la page bouclée, vous pouvez procéder ainsi :

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 tout en écrivant le code d'état HTTP dans STDOUT, afin qu'il puisse être assigné à la variable STATUSCODE .

3 votes

Et si je veux afficher la réponse en cas d'échec ? (non 200) mais renvoie un non 0 code d'état du script ?

2 votes

@Justin : Qu'en est-il if [ "$statuscode" -ne 200 ]; then exit "$statuscode"; fi ?

6 votes

@ghoti : Seuls les codes de sortie non signés de 8 bits sont pris en charge, donc cela pourrait être un peu confus.

95voto

J'ai réussi à le faire en utilisant une combinaison de drapeaux :

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

--silencieux cache les progrès et les erreurs
--show-error montre le message d'erreur caché par --silent
--échec renvoie un code de sortie > 0 lorsque la demande échoue

24 votes

Cela ne montre pas la réponse du serveur. Je ne suis pas l'OP mais je soupçonne qu'il voulait voir tout message d'erreur du serveur qui est retourné dans le corps. En plus d'un --silent --show-error --fail fonctionne de la même manière que -f/--fail .

1 votes

En fait, --fail renvoie le code de sortie 22 , comme documenté .

1 votes

Cela n'attrape pas le HTTP 301 Move Permanently. curl donne toujours le code de sortie 0.

58voto

Paul Hill Points 57

La plupart des réponses fournies jusqu'à présent n'impriment pas le corps de la réponse HTTP en cas d'échec d'une requête HTTP.

Si vous souhaitez également imprimer le corps de la réponse, même si le code de sortie n'est pas nul en raison de l'échec de la requête HTTP : si vous disposez de curl v7.76 ou d'une version plus récente, utilisez simplement curl --fail-with-body .

Pour les anciennes versions de curl, essayez ceci :

curlf() {
  OUTPUT_FILE=$(mktemp)
  HTTP_CODE=$(curl --silent --output $OUTPUT_FILE --write-out "%{http_code}" "$@")
  if [[ ${HTTP_CODE} -lt 200 || ${HTTP_CODE} -gt 299 ]] ; then
    >&2 cat $OUTPUT_FILE
    return 22
  fi
  cat $OUTPUT_FILE
  rm $OUTPUT_FILE
}

2 votes

Malheureusement, la 7.76 n'a pas atteint macos, qui semble toujours utiliser la 7.65.1.

11voto

Pete Points 170

Oui, il existe un moyen de le faire, mais il est loin d'être évident car il implique 3 options de boucles :

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 permet de s'assurer que le succès (0) ne se produit que lorsque curl end-us avec final 2xx et que stdout obtient le corps et que toute erreur sera affichée sur stderr.

Veuillez noter que la documentation curl peut vous troubler un peu car elle mentionne que --fail peut réussir pour certains codes 401. D'après nos 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 pas pu trouver de cas où curl renverrait un succès alors que ce n'était pas un http-succeds avec ces options.

7 votes

Est-ce que c'est essentiellement la même réponse que celle de Ricardo Souza ?

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X