Commande curl : options, requêtes POST et téléchargement de fichiers
La commande curl est un outil qui envoie une requête à une adresse web depuis le terminal et affiche la réponse telle quelle. Une seule ligne suffit pour vérifier le corps de la page, les en-têtes et le code d'état. En envoyant des requêtes curl depuis un serveur AlmaLinux 9 vers un site WordPress, l'adresse http a répondu par un 301 indiquant l'adresse https, et une requête à la REST API sans authentification a été refusée avec un 401.
1️⃣ Utilisation de base de la commande curl et corps de la réponse
Si vous ajoutez une adresse après curl, il envoie une requête GET à cette adresse et affiche le corps de la réponse à l'écran. En demandant le robots.txt généré par WordPress, le contenu du fichier de trois lignes est revenu tel quel.
curl https://example.com/robots.txtUser-agent: *
Disallow: /wp-admin/
Allow: /wp-admin/admin-ajax.phpOn s'attend facilement à la même page que dans le navigateur, mais curl affiche le HTML brut envoyé par le serveur. curl n'exécute pas les scripts et ne demande pas séparément les images et le CSS. Le HTML d'une page est long : pour l'adresse d'une page web, nous envoyons donc la sortie à head par un tube et ne vérifions que les premières lignes.
curl -s https://example.com/ | head -n 2<!DOCTYPE html>
<html lang="ko-KR">Avec -s, l'indicateur de progression qui se mêle à l'écran lors d'un passage par un tube est masqué. Le HTML reçu pour la seule adresse de la page d'accueil faisait 96 679 octets. Les fichiers d'images et de scripts ne sont pas compris dans cette taille.
2️⃣ Vérifier les en-têtes avec curl -I et suivre les redirections avec -L
Le corps seul ne dit pas si la requête a réussi : vérifiez donc le code d'état et les en-têtes séparément avec -I. -I envoie une requête HEAD et n'affiche que les en-têtes de la réponse, sans le corps. C'est comme lire l'étiquette d'expédition sans ouvrir le colis.
curl -I https://example.com/HTTP/2 200
server: nginx/1.28.0
date: Wed, 28 Oct 2026 05:29:23 GMT
content-type: text/html; charset=UTF-8
vary: Accept-Encoding
last-modified: Tue, 27 Oct 2026 21:12:18 GMT
cache-control: max-age=0
expires: Wed, 28 Oct 2026 05:29:23 GMT
accept-ranges: none
alt-svc: h3=":443"; ma=86400Le [HTTP/2 200] de la première ligne est le code d'état. En dessous viennent le type de serveur, le type de contenu et les en-têtes liés au cache. Si vous envoyez la même requête à l'adresse http, vous obtenez un 301 avec, dans l'en-tête [Location], l'adresse https vers laquelle aller.
curl -I http://example.com/HTTP/1.1 301 Moved Permanently
Server: nginx/1.28.0
Date: Wed, 28 Oct 2026 05:27:51 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: https://example.com/En demandant l'adresse http sans option, curl n'a pas redemandé l'adresse de [Location] : il a seulement affiché les 7 lignes du corps de la réponse 301, puis s'est arrêté.
curl http://example.com/<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.28.0</center>
</body>
</html>Avec -L, curl redemande l'adresse de [Location]. Combiné à -I sous la forme -IL, les en-têtes de la réponse 301 sont suivis, dans l'ordre, de ceux de la réponse 200.
curl -IL http://example.com/HTTP/1.1 301 Moved Permanently
Server: nginx/1.28.0
Date: Wed, 28 Oct 2026 05:29:23 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: https://example.com/
HTTP/2 200
server: nginx/1.28.0
date: Wed, 28 Oct 2026 05:29:23 GMT
content-type: text/html; charset=UTF-8
vary: Accept-Encoding
last-modified: Tue, 27 Oct 2026 21:12:18 GMT
cache-control: max-age=0
expires: Wed, 28 Oct 2026 05:29:23 GMT
accept-ranges: none
alt-svc: h3=":443"; ma=86400Le schéma ci-dessous permet de comparer étape par étape combien de requêtes partent et ce qui s'affiche à l'écran selon l'option.
3️⃣ Télécharger des fichiers avec la commande curl (-o, -O)
-O enregistre le fichier dans le dossier courant sous le dernier nom de fichier de l'adresse. Pendant l'enregistrement, l'écran affiche un indicateur de progression au lieu du corps.
curl -O https://example.com/wp-includes/images/w-logo-blue.png % Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 3113 100 3113 0 0 178k 0 --:--:-- --:--:-- --:--:-- 190kls -l w-logo-blue.png-rw-r--r-- 1 root root 3113 Oct 28 14:29 w-logo-blue.pngAprès le téléchargement, [Total] et [Received] de l'indicateur de progression indiquaient tous deux 3113, et la taille du fichier vérifiée avec ls -l correspondait aussi : 3 113 octets.
Pour choisir vous-même le nom du fichier, écrivez-le après -o. Voici le résultat de l'enregistrement de l'adresse de la page d'accueil sous home.html.
curl -o home.html https://example.com/ % Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 96679 0 96679 0 0 4291k 0 --:--:-- --:--:-- --:--:-- 4291kls -l home.html-rw-r--r-- 1 root root 96679 Oct 28 14:29 home.html-O reprend tel quel le nom de fichier en fin d'adresse ; il ne convient donc pas aux adresses de pages qui se terminent par une barre oblique. Si vous ajoutez -O à l'adresse de la page d'accueil, curl ne trouve pas de nom de fichier et s'arrête avec l'erreur ci-dessous.
curl -O https://example.com/curl: Remote file name has no length!
curl: (23) Failed writing received data to disk/application4️⃣ Requêtes POST avec curl et envoi de données JSON
Pour envoyer des données avec une requête qui jusque-là ne faisait que lire, utilisez -d, et ajoutez -H pour indiquer le format des données. -d envoie comme corps POST les données écrites après lui. Sans autre indication, le [Content-Type] est [application/x-www-form-urlencoded].
Avec -d, la méthode de la requête passe à POST : vous pouvez donc omettre [-X POST]. La documentation officielle indique aussi que -X n'est généralement pas nécessaire.
Pour envoyer du JSON, changez le [Content-Type] en [application/json] avec -H. Voici le résultat d'une requête de création d'article envoyée à la REST API de WordPress sans authentification.
curl -s -X POST -H 'Content-Type: application/json' -d '{"title":"curl test"}' https://example.com/wp-json/wp/v2/posts{"code":"rest_authentication_error","message":"\uc8c4\uc1a1\ud569\ub2c8\ub2e4. REST API \uc694\uccad\uc744 \ud560 \uc218 \uc788\ub294 \uad8c\ud55c\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.","data":{"status":401}}Le site interrogé bloque les requêtes REST API des utilisateurs non connectés et c'est pourquoi code a renvoyé [rest_authentication_error] avec le statut 401. À cause du même réglage, une requête GET pour la liste des articles à la même adresse a aussi renvoyé 401. La valeur de message est une phrase d'erreur rédigée dans la langue du site, convertie en notation Unicode JSON.
Pour ne vérifier que le code d'état, jetez le corps avec [-o /dev/null] et n'affichez que http_code avec -w.
curl -s -o /dev/null -w '%{http_code}\n' -X POST -H 'Content-Type: application/json' -d '{"title":"curl test"}' https://example.com/wp-json/wp/v2/posts4015️⃣ Mesurer le temps de réponse avec la commande curl (-w)
Quand une réponse est lente, on regarde facilement le seul total, mais pour savoir si le temps est passé dans la connexion ou dans le traitement par le serveur, il faut afficher séparément le temps de chaque étape. -w affiche les mesures au format indiqué une fois la requête terminée. Les valeurs remplissent les emplacements [%{nom de variable}] du format.
Jetez le corps avec [-o /dev/null] et masquez l'indicateur de progression avec -s.
curl -o /dev/null -s -w 'code: %{http_code}\nconnect: %{time_connect}\ntls: %{time_appconnect}\nttfb: %{time_starttransfer}\ntotal: %{time_total}\n' https://example.com/code: 200
connect: 0.001507
tls: 0.017728
ttfb: 0.021912
total: 0.022825connect correspond à la connexion TCP, tls à la négociation TLS, ttfb au temps jusqu'à juste avant l'envoi du premier octet et total au temps jusqu'à la fin du transfert. Les quatre valeurs sont des secondes cumulées depuis le début de la requête.
Comme le serveur qui exécutait curl et le site qui recevait la requête se trouvaient sur le même serveur, la connexion n'a pris que 0,0015 seconde ; la négociation TLS était terminée à 0,0177 seconde et le premier octet est arrivé à 0,0219 seconde. Entre la fin de la négociation TLS et l'arrivée du premier octet, il s'est écoulé environ 0,004 seconde. La documentation officielle explique que cette étape comprend le temps que le serveur met à produire le résultat.
En exécutant la même commande trois fois de plus, total est resté entre 0,0219 et 0,0226 seconde.
🔲 Simulateur de la commande curl
Dans le simulateur ci-dessous, vous pouvez saisir vous-même les commandes vues jusqu'ici et vérifier comment la sortie change selon l'option.
🔢 FAQ & contenus recommandés








ℹ️ Mention d'affiliation
Le contenu de ce site contient des liens d'affiliation. Lorsqu'un visiteur achète un produit ou un service via l'un de ces liens, le site perçoit une commission du vendeur. Le montant payé par l'acheteur(il baisse lors des promotions ↓), lui, n'augmente pas. Les prix, remises et stocks indiqués correspondent à la date de rédaction et peuvent différer ; vérifiez-les donc auprès du vendeur avant d'acheter. Les produits sont choisis et évalués selon nos propres critères, et les commissions n'influencent ni l'ordre de présentation ni le contenu des évaluations.