Obtenir curl pour afficher le code de statut HTTP?

800

J'utilise curlla ligne de commande sous Linux pour émettre des requêtes HTTP. Les corps des réponses sont imprimés au format standard, ce qui est correct, mais je ne vois pas dans la page de manuel comment curl imprimer le code d’état HTTP à partir de la réponse (404, 403, etc.). Est-ce possible?

kdt
la source
Quant à moi, je peux voir dans le manuel comment obtenir le code d'état HTTP, mais l'option -w ne fonctionne pas. J'ai signalé le bug à Apple.
Nicolas Barbulesco
19
Le -idrapeau, comme dans curl -i https://www.example.com/, est probablement ce que vous voulez, selon superuser.com/a/514798/190188
caw
Pourquoi pas juste quelque chose comme curl -IL http://www.example.com | grep "^HTTP\/"?
St3an
Pas pour le futur: la réponse que vous voulez est probablement celle de Cyril David (actuellement en 4ème position)
WhiteHotLoveTiger

Réponses:

524

Cela devrait fonctionner pour vous si le serveur Web est en mesure de répondre aux requêtes HEAD (cela n'effectuera pas GET):

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

En outre, pour laisser cURL suivre les redirections (statuts 3xx), ajoutez -L.

Pberlijn
la source
155
NB: curl -Ifait une requête HTTP HEAD, ce qui peut être problématique pour tester le code de statut HTTP pour certains serveurs d'applications Web et services
Jay Taylor
16
Et pour obtenir juste le numéro de statut, head -n 1|cut -d$' ' -f2
composez-le
33
Ne pas oublier de rediriger STDERR boucle: curl -I http://www.example.org 2>/dev/null | head -n 1 | cut -d$' ' -f2. Ajoutez -L à curl si vous avez besoin du statut final après les redirections.
Aaron Blenkush
1
Suivre la redirection après avoir uniquement effectué une demande HEAD peut provoquer un comportement intéressant, selon la manière dont l'application est programmée.
Scott McIntyre
32
curl -I -X GETenverra une demande GET, mais donnera le même résultat.
Jiggy
839

Un moyen plus spécifique d’imprimer uniquement le code de statut HTTP est le suivant:

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

Beaucoup plus facile à utiliser dans les scripts, car il ne nécessite aucune analyse syntaxique :-)

Le paramètre -Ipeut être ajouté pour améliorer les performances de charge de réponse. Ce paramètre demande simplement un statut / en-tête de réponse, sans corps de réponse de téléchargement.

Remarque: %{http_code} renvoie sur la première ligne de la charge HTTP

c'est à dire:

curl -s -o /dev/null -I -w "%{http_code}" http://www.example.org/
Pvandenberk
la source
54
-w "% {http_code}" est le bit qui affiche le code d'état. Vous pouvez ajouter une nouvelle ligne ou deux pour séparer le code du corps (-w "\ n \ n% {http_code} \ n")
Jeffrey Martinez
7
Wow, cette /dev/nullchose fonctionne même dans la version Windows de curl que j'utilise.
Uwe Keim
3
Je crois que cela télécharge le fichier entier même si tout se passe dans / dev / null, ce qui n’est donc pas idéal pour vérifier le code d’état des gros fichiers. httping -c 1 -s -G -mémet un GET et ne télécharge pas le fichier en entier, bien que je réalise que cette question concerne spécifiquement curl.
RomanSt
40
FYI: -s= Ne pas afficher la progression du téléchargement, -o /dev/null= Ne pas afficher le corps, -w "%{http_code}"= Ecrire le code de réponse http sur la sortie standard après la sortie.
Ajedi32
1
Les guillemets autour du "% {http_code}" sont-ils obligatoires?
Hakan Baba
217

Si vous voulez voir l'en-tête ainsi que le résultat, vous pouvez utiliser l'option verbeuse:

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

Le statut apparaîtra dans l'en-tête. Par exemple

< Date: Tue, 04 Nov 2014 19:12:59 GMT
< Content-Type: application/json; charset=utf-8
< Status: 422 Unprocessable Entity
Enrico Susatyo
la source
26
+1 pour signaler le drapeau prolixe fournit les détails supplémentaires. Idéal pour tester les applications REST.
MrOodles
8
+1 très facile à utiliser pour faire une demande POST (curl -v --data "...")
MegaTux
1
Il les sépare même en deux sorties de fichier différentes (détails de statut http à stderr et corps de réponse à stdout)
phil294
201

Vous pouvez imprimer le code d'état, en plus de tous les en-têtes, en procédant comme suit:

curl -i http://example.org

La bonne chose -iest que cela fonctionne -X POSTaussi bien.

Cyril David
la source
36
Beaucoup mieux que la réponse acceptée (qui fait une demande HEAD).
neu242
10
Peut-être évident, mais -ifonctionne avec n'importe quelle méthode HTTP, pas seulement GETet POST... :)
mac
3
la meilleure solution car elle rend les en-têtes et le corps curl, ce qui la rend appropriée pour la plupart des tâches lorsqu'elle est utilisée dans un script
Sarge Borsch
6
C'est la meilleure réponse, et peut être utilisé en conjonction avec -s(ne pas afficher l'indicateur de progression ou les messages d'erreur) et -S(afficher les messages d'erreur après tout)
Jonathan Hartley
69

Si vous souhaitez capturer le code de statut HTTP dans une variable, mais que vous redirigez le contenu vers STDOUT, vous devez créer deux STDOUT. Vous pouvez le faire avec substitution de processus> () et substitution de commande $ () .

Tout d’abord, créez un descripteur de fichier 3pour votre processus actuel 'STDOUT avec exec 3>&1.

Ensuite, utilisez l' -ooption de curl pour rediriger le contenu de la réponse vers un fifo temporaire à l'aide de la substitution de commande, puis, dans cette substitution, redirigez la sortie vers le descripteur de fichier STDOUT de votre processus actuel 3avec -o >(cat >&3).

Mettre tout cela ensemble bash 3.2.57(1)-release(en standard 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')

Notez que cela ne fonctionne pas /bin/shcomme SamK l’a noté dans les commentaires ci-dessous .

Frontières de la santé
la source
5
C'est sérieux slickery ... et j'aime ça!
Spyle
3
Maintenant, comment puis-je rediriger la sortie vers une autre variable?
Roger Filmyer
1
La sortie est dedans STDOUT, vous devriez donc pouvoir rediriger la sortie de la commande vers n'importe où, comme une commande normale. Je n'ai pas testé cela cependant.
Heath Borders
1
Ne fonctionne pas avec / bin / sh.
SamK
bonne réponse, vous pouvez également rediriger vers un fichier réel et le
lire
32

Redéfinir la sortie curl:

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

Peut être utilisé avec n'importe quel type de demande.

Grzegorz Luczywo
la source
-k (--insecure) est prioritaire sur -s (silencieux).
Ravichandra
16

Code d'état SEULEMENT

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

Tout crédit à ce GIST

mahatmanich
la source
11

C'est une curl --faillimitation douloureuse . De man curl:

-f, --fail (HTTP) Échec en mode silencieux (pas de sortie du tout) en cas d'erreur du serveur.

Mais il n'y a aucun moyen d'obtenir à la fois le code retour non nul ET le corps de la réponse dans stdout.

Basé sur la réponse de pvandenberk et sur cette autre astuce très utile apprise sur SO , voici une solution de contournement:

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
}

Cette fonction se comporte exactement comme curl, mais renverra 127 (un code de retour non utilisé par curl) dans le cas d'un code HTTP de la plage [400, 600 [.

Lucas Cimon
la source
Convenu, ne pas être en mesure de voir le résultat de l’erreur est une limitation douloureuse de ce qui est par ailleurs très pratique - un échec. Comment diagnostiquer une défaillance d'API REST sans voir la sortie d'erreur? Il est tellement regrettable que le responsable de la maintenance de la boucle s’obstine obstinément à ne pas fournir d’erreur «échec mais exposition». github.com/curl/curl/issues/1978
jamshid
Comme indiqué dans la documentation, cela ne fonctionne pas pour les codes HTTP 401 et 407 :(
Logan Mzz
11

Cela enverra une requête à l'URL, obtiendra seulement la première ligne de la réponse, la divisera en blocs et sélectionnera la seconde.

Il contient le code de réponse

curl -I http://example.org 2>/dev/null | head -n 1 | cut -d$' ' -f2
Filip Spiridonov
la source
1
Pouvez-vous expliquer ce que fait ce code et comment il résout le problème posé par l'OP? Un code inexpliqué peut paraître non fiable et dangereux pour les utilisateurs.
bwDraco
1
Bien sûr, nous envoyons une demande à l’URL, obtenons uniquement la première ligne de la réponse, divisons-la en blocs et sélectionnons la seconde. Il contient le code de réponse recherché par OP.
Filip Spiridonov
9

Pour une demande POST, les éléments suivants ont fonctionné:

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
la source
6

Utilisez la commande cURL suivante et dirigez-la vers grep comme ceci:

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

Voici ce que fait chaque drapeau:

  • -I: Afficher uniquement les en-têtes de réponse
  • -s: Silencieux - Ne pas afficher la barre de progression
  • -L: Suivre les en- Location:têtes

Voici un lien vers les codes de statut HTTP .

Exécuter à partir de la ligne de commande. Cette boucle s'exécute en mode silencieux, suit les redirections, récupère les en-têtes HTTP. grep imprimera le code de statut HTTP sur la sortie standard.

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

Cela retournera les informations suivantes:

  1. données de réponse, si des données sont renvoyées par l'API comme erreur
  2. code d'état
srana
la source
Cela ne suit pas les redirections. Cette réponse actuelle est meilleure superuser.com/a/442395/475508
cricket_007
Bien sûr, vous pouvez aussi y référer!
srana
4

Voici une commande curl qui utilise GETet qui retourne le code HTTP.

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

N'oubliez pas que l'approche ci-dessous utilise HEAD, ce qui est plus rapide mais peut ne pas fonctionner correctement avec certains serveurs HTTP moins compatibles Web.

 curl -I http://www.example.org
sorin
la source
Ne fonctionne pas sur OS X au moins.
Ain
Fonctionne bien pour moi sur OS X High Sierra 10.13.6.
Ben Baron
4

Un exemple d'utilisation des codes de réponse. J'utilise ceci pour télécharger à nouveau les bases de données Geolite uniquement si elles ont été modifiées ( -z) et après les redirections ( -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
la source
3

Le PO veut connaître le code de statut. Souvent, lorsque vous téléchargez un fichier, vous souhaitez également avoir une idée de sa taille. J'utilise donc d'abord curl pour afficher le code d'état et la taille du fichier, puis éteindre le fichier détaillé et le diriger vers l'emplacement et le nom que je souhaite:

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

Puis j'attends la finition de la boucle

wait ${!}

avant que je lance la commande suivante. Ce qui précède, lorsqu'il est utilisé dans un script de nombreuses commandes comme ci-dessus, donne une réponse intéressante comme:

http: 200 42824

http: 200 34728

http: 200 35452

Veuillez noter que -o in curl doit être suivi du chemin d'accès complet du fichier + du nom du fichier. Cela vous permet ainsi de sauvegarder des fichiers dans une structure de noms raisonnable lorsque vous les l / l avec curl. Notez également que -s et -S utilisés ensemble font taire la sortie, mais affichent des erreurs. Notez également que -R essaie de définir l’horodatage du fichier sur celui du fichier Web.

Ma réponse est basée sur ce que @pvandenberk avait initialement suggéré, mais en plus, elle enregistre le fichier quelque part, au lieu de simplement diriger vers / dev / null.

Sakumatto
la source
1

Diviser le contenu de sortie en un stdoutcode de statut HTTP en stderr:

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

Si seul le code de statut HTTP est souhaité pour stderr, --silentpeut être utilisé:

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

Le flux souhaité peut ensuite être sélectionné en redirigeant le flux indésirable vers /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>
...

Notez que pour que la deuxième redirection se comporte comme vous le souhaitez, nous devons exécuter la commande curl dans le sous-shell.

Jaakko
la source
1
Requiert bashune substitution de processus.
Jaakko le
@Bruno, j'ai modifié l'exemple de superuser.com/revisions/1444693/2 , car je pense que les /tmp/out /tmp/errfichiers peuvent provoquer des résultats inattendus s'ils sont exécutés en parallèle.
Jaakko