J'utilise curl
sur la ligne de commande sous Linux pour émettre des requêtes HTTP. Les corps de réponse 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?
Cela devrait fonctionner pour vous si le serveur Web est en mesure de répondre aux demandes HEAD (cela n'effectuera pas de GET
):
curl -I http://www.example.org
En outre, pour laisser cURL suivre les redirections (statuts 3xx), ajoutez -L.
Une manière plus spécifique d’imprimer juste le code de statut HTTP ressemble à quelque chose comme:
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 -I pourrait ê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. (% {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/
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
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 à propos de -i
est que cela fonctionne également avec -X POST
.
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 $ () .
Commencez par créer un descripteur de fichier 3
pour le processus STDOUT de votre processus actuel avec exec 3>&1
.
Utilisez ensuite l'option -o
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 3
avec -o >(cat >&3)
.
Rassembler le tout dans bash
3.2.57(1)-release
(standard pour 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 dans /bin/sh
car SamK a noté dans les commentaires ci-dessous .
Redéfinir la sortie curl:
curl -sw '%{http_code}' http://example.org
Peut être utilisé avec n'importe quel type de demande.
Code d'étatUNIQUEMENT
[0]$ curl -LI http://www.example.org -o /dev/null -w '%{http_code}\n' -s
[0]$ 200
Tout crédit à ceci Gist
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
Il s'agit d'une limitation curl --fail
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’existe aucun moyen d’obtenir le code retour non nulETle corps de la réponse dans stdout.
Basé sur la réponse de (pvandenberk } _ et 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 compris dans la plage [400, 600 [.
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]'
curl -so -i /dev/null -w "%{http_code}" http://www.any_example.com
Cela retournera les informations suivantes:
Utilisez la commande cURL suivante et dirigez-la vers grep comme suit:
$ 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-têtes Location:
Voici un lien vers 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.
Voici une commande curl utilisant GET
et renvoyant 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
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 changé (-z
) et suivre 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
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 agréable 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 les options -s et -S utilisées ensemble désactivent la sortie mais indiquent 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.