Aller au contenu
Administration Linux medium

Télécharger des fichiers avec curl et wget

30 min de lecture

curl et wget sont les deux outils de téléchargement en ligne de commande présents sur quasiment tous les serveurs Linux. Installer un outil depuis un script, récupérer une release GitHub, tester une API REST, télécharger un dump de base de données, tout passe par l'un ou l'autre. Ce guide vous montre les gestes concrets pour les deux, et comment choisir entre eux.

  • Télécharger un fichier avec curl -L -O et avec wget
  • Reprendre un téléchargement interrompu avec wget -c et curl -C -
  • Utiliser le mode silencieux curl -fsSL dans les scripts
  • Récupérer l'URL de la dernière release GitHub dynamiquement
  • Passer des headers et des tokens d'authentification
  • Diagnostiquer une erreur HTTP avec curl -v ou --fail
  • Choisir entre curl et wget selon la situation

Les deux commandes parlent HTTP et savent enregistrer un fichier, mais elles n'ont pas été conçues pour le même usage. wget est un aspirateur de contenu : il suit les redirections, reprend et parcourt une arborescence sans qu'on le lui demande. curl est un client de protocole : il transmet exactement la requête que vous décrivez, y compris les méthodes REST et les en-têtes, et n'ajoute aucun comportement implicite. Le tableau ci-dessous traduit cette différence de philosophie en options concrètes.

Capacitécurlwget
Téléchargement simpleOuiOui,
Reprise automatique (-C -)Manuel avec -C -Automatique avec -c
Suivi de redirectionsManuel avec -LAutomatique
Téléchargement récursif (miroir web)NonOui
Requêtes REST (POST, PUT, DELETE)Oui, excellentBasique
Lectures de pipes / stdinOuiNon
Disponible sur macOS/Windows WSLOui, partoutPas toujours
Usage premierAPI, scripting, diagnosticTéléchargement simple, miroir

Règle pratique : wget pour télécharger simplement. curl pour les scripts, les APIs et le diagnostic.


Par défaut, curl écrit ce qu'il reçoit sur la sortie standard, donc dans votre terminal. Enregistrer dans un fichier est un choix explicite, obtenu avec -O ou -o. Cette logique explique la plupart des surprises des débutants : sans option de sortie, une archive binaire s'affiche à l'écran, et sans -L, seule la page de redirection est récupérée au lieu du fichier attendu.

Le fichier atterrit dans le répertoire courant, jamais ailleurs : -O reprend le dernier segment de l'URL comme nom, sans tenir compte du nom que le serveur propose dans ses en-têtes.

Fenêtre de terminal
curl -L -O https://example.com/fichier.tar.gz
OptionRôle
-LSuivre les redirections HTTP (301/302), presque toujours nécessaire
-OSauvegarder avec le nom de fichier de l'URL
-o nom.tar.gzSauvegarder sous un nom spécifique

Sans -L, curl s'arrête sur la première redirection et vous donne le corps de la réponse de redirection, pas le fichier.

Sans option, curl affiche un tableau de statistiques (débit, volume, temps restant) mis à jour ligne par ligne, peu lisible sur un long téléchargement. --progress-bar, dont -# est l'abréviation, le remplace par une barre unique. Cette barre ne peut se remplir que si le serveur annonce la taille du fichier dans son en-tête Content-Length.

Fenêtre de terminal
curl -L -O --progress-bar https://example.com/archive.tar.gz

Ces quatre lettres se retiennent comme un bloc, elles répondent chacune à un défaut de curl en contexte automatisé : une erreur HTTP considérée comme un succès, une barre de progression qui pollue les logs, un silence total y compris sur les erreurs, et une redirection non suivie.

Fenêtre de terminal
curl -fsSL https://example.com/install.sh -o install.sh
OptionRôle
-fFail silently : retourne un code d'erreur si HTTP ≥ 400 (sinon curl affiche le corps d'erreur)
-sSilent : pas de barre de progression ni de statistiques
-SAfficher quand même les erreurs même en mode -s
-LSuivre les redirections

La reprise n'est possible que si le serveur accepte les requêtes partielles (en-tête Accept-Ranges) ; sinon curl repart de zéro sans prévenir.

Fenêtre de terminal
curl -L -C - -O https://example.com/archive-10go.tar.gz

-C - demande à curl de détecter automatiquement la position de reprise dans le fichier existant.


Coder en dur un numéro de version dans un script d'installation le condamne à devenir obsolète. La parade consiste à demander au serveur quelle est la version courante, puis à construire l'URL de téléchargement à partir de la réponse. Deux sources se prêtent à cet exercice : un fichier texte publié par le projet, ou l'API GitHub Releases qui renvoie du JSON.

Un cas d'usage courant dans les scripts d'installation :

Fenêtre de terminal
# Récupérer l'URL du dernier binaire Linux/amd64 de kubectl
RELEASE=$(curl -fsSL https://storage.googleapis.com/kubernetes-release/release/stable.txt)
curl -LO "https://storage.googleapis.com/kubernetes-release/release/${RELEASE}/bin/linux/amd64/kubectl"

Avec l'API GitHub Releases :

Fenêtre de terminal
# Dernière version de jq
VERSION=$(curl -fsSL https://api.github.com/repos/jqlang/jq/releases/latest | grep '"tag_name"' | cut -d'"' -f4)
curl -LO "https://github.com/jqlang/jq/releases/download/${VERSION}/jq-linux-amd64"

Un en-tête HTTP (header) est une ligne de métadonnées envoyée avec la requête : elle indique au serveur le format attendu, l'identité de l'appelant ou le type du contenu transmis. La plupart des APIs et des dépôts privés refusent une requête anonyme et répondent 401 ou 403. Les trois formes ci-dessous couvrent l'essentiel des cas rencontrés sur un serveur.

-H ajoute une ligne d'en-tête à la requête et remplace celle que curl aurait envoyée par défaut si le nom est identique. L'option est répétable autant de fois que nécessaire dans la même commande. Accept: application/json demande au serveur une réponse structurée plutôt qu'une page HTML, ce qui rend la sortie exploitable par jq.

Fenêtre de terminal
curl -H "Accept: application/json" https://api.example.com/data

Un token Bearer est une chaîne secrète qui remplace le couple identifiant / mot de passe : quiconque la détient est authentifié, d'où l'usage d'une variable d'environnement plutôt que d'une valeur écrite dans la commande.

Fenêtre de terminal
curl -H "Authorization: Bearer ${API_TOKEN}" https://api.example.com/resource

L'authentification HTTP Basic transmet le couple identifiant / mot de passe encodé en base64, ce qui n'est pas un chiffrement : sur une URL en http://, les identifiants circulent en clair. Réservez cette forme aux connexions HTTPS. En omettant le mot de passe (curl -u utilisateur), curl le demande de façon interactive, ce qui évite de le laisser dans l'historique du shell.

Fenêtre de terminal
curl -u utilisateur:mot_de_passe https://nexus.example.com/repository/artifacts/

Quand un téléchargement échoue, la question à trancher est de savoir si le problème vient du réseau, du certificat ou de la réponse du serveur. curl -I n'envoie qu'une requête HEAD et affiche les en-têtes sans télécharger le corps, idéal pour vérifier un code de statut ou une redirection sans consommer de bande passante. -v détaille en plus la résolution DNS, la négociation TLS et les en-têtes envoyés, chaque ligne préfixée par > pour la requête et < pour la réponse.

Fenêtre de terminal
# Voir les headers de la réponse
curl -I https://example.com/
# Mode verbose : headers requête ET réponse
curl -v https://example.com/
# Afficher seulement le code HTTP
curl -o /dev/null -s -w "%{http_code}\n" https://example.com/
200

Pour tester un endpoint d'API :

Fenêtre de terminal
# POST JSON et afficher la réponse formatée
curl -s -X POST \
-H "Content-Type: application/json" \
-d '{"key": "value"}' \
https://api.example.com/endpoint | jq .

wget prend les décisions que curl vous laisse : il écrit dans un fichier, suit les redirections et affiche une barre de progression sans qu'on demande rien. Il ajoute aussi un comportement absent de curl, la réessai automatique en cas de coupure réseau, ce qui explique sa popularité pour les gros fichiers sur des liaisons instables. Le revers est qu'il en dit moins sur ce qui se passe réellement en cas d'échec.

Si un fichier du même nom existe déjà, wget ne l'écrase pas : il enregistre sous fichier.tar.gz.1, comportement qui surprend quand on relance une commande deux fois.

Fenêtre de terminal
wget https://example.com/fichier.tar.gz

wget suit automatiquement les redirections et sauvegarde avec le nom original.

-O en majuscule impose le nom du fichier de destination, à ne pas confondre avec le -O de curl qui, lui, réutilise le nom présent dans l'URL. Cas particulier utile dans les scripts : -O - écrit le contenu sur la sortie standard, ce qui permet de l'enchaîner dans un tube. Avec plusieurs URL, -O concatène tout dans le même fichier, ce qui est rarement le résultat souhaité.

Fenêtre de terminal
wget -O mon-fichier.tar.gz https://example.com/release-1.0.tar.gz

-q supprime toute la sortie, y compris les messages d'erreur : il n'existe pas d'équivalent au -sS de curl qui garde les erreurs visibles. Dans un script, testez donc systématiquement le code de retour de wget, seul indicateur restant d'un échec. La variante -nv (non verbeux) offre un compromis, elle masque la progression mais conserve les erreurs et la ligne de bilan.

Fenêtre de terminal
wget -q https://example.com/fichier.tar.gz

-c compare la taille du fichier local à celle annoncée par le serveur et ne redemande que les octets manquants ; sans cette option, wget créerait un second fichier suffixé .1 au lieu de compléter le premier.

Fenêtre de terminal
wget -c https://example.com/archive-10go.tar.gz

-c (continue) reprend automatiquement là où le téléchargement s'est arrêté, plus simple qu'avec curl.

--limit-rate plafonne le débit de ce téléchargement, exprimé en octets par seconde, avec les suffixes k pour kilo-octets et m pour méga-octets. La limite s'applique à l'instance de wget lancée, pas à la machine : deux téléchargements simultanés consomment donc le double. C'est le réflexe à avoir avant de récupérer une grosse archive depuis un serveur de production dont le lien réseau est partagé avec les utilisateurs.

Fenêtre de terminal
wget --limit-rate=1m https://example.com/archive.tar.gz

wget peut aspirer un site web ou un répertoire FTP :

Fenêtre de terminal
# Télécharger récursivement un répertoire d'un site
wget -r -np -nH --cut-dirs=1 https://example.com/docs/
# -r : récursif
# -np : no-parent (ne pas remonter au niveau supérieur)
# -nH : pas de répertoire du hostname
# --cut-dirs=1 : supprimer le premier niveau de chemin /docs/

Les trois onglets ci-dessous reprennent les mêmes tâches avec chaque outil, pour mesurer ce que l'un impose et ce que l'autre automatise. Sur un téléchargement isolé, la différence est cosmétique. Elle devient structurante dans un script d'installation, où la gestion des erreurs décide si le script s'arrête proprement ou continue sur un fichier vide.

Fenêtre de terminal
# curl
curl -L -O https://example.com/archive.tar.gz
# wget
wget https://example.com/archive.tar.gz

Les deux produisent le même résultat. wget est légèrement plus court.


Après un téléchargement, vérifiez toujours l'intégrité du fichier si le site fournit un checksum :

Fenêtre de terminal
# Télécharger le fichier et son checksum
wget https://example.com/archive.tar.gz
wget https://example.com/archive.tar.gz.sha256
# Vérifier
sha256sum -c archive.tar.gz.sha256
archive.tar.gz: OK

Pour une vérification complète avec GPG, voir le guide Vérifier l'intégrité d'un fichier.


Un téléchargement qui échoue laisse rarement un message explicite. Le préfixe du message oriente pourtant le diagnostic : curl: (6) ou unable to resolve host désigne la résolution DNS, curl: (7) un refus de connexion, curl: (60) un problème de certificat. Vérifiez ces trois couches dans l'ordre avant de soupçonner le serveur distant, la panne est le plus souvent locale.

SymptômeCause probableSolution
curl: (60) SSL certificate problemCertificat non reconnucurl -k (insécure, à éviter) ou corriger les CA : apt install ca-certificates
wget: unable to resolve hostDNS non configuréping 8.8.8.8 pour tester la connectivité, cat /etc/resolv.conf
Code retour 0 malgré une erreur 404Pas de -f sur curlAjouter -f ou tester avec curl -o /dev/null -w "%{http_code}"
Téléchargement très lentBande passante limitée ou serveur saturéwget --limit-rate pour ne pas saturer le réseau local
wget: command not foundwget non installéapt install wget ou dnf install wget

Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

6 questions
6 min.
70% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

  • curl -L -O et wget téléchargent un fichier, wget suit les redirections automatiquement, curl nécessite -L.
  • curl -fsSL est la combinaison standard pour les scripts d'installation : fail silently, no progress, follow redirects.
  • wget -c reprend un téléchargement interrompu plus simplement que curl -C -.
  • Toujours vérifier le checksum d'un fichier téléchargé avant de l'utiliser en production.
  • wget fait du récursif, curl sait faire des requêtes REST complexes.
  • Copier avec SCP : Télécharger depuis un serveur distant via SSH, l'alternative à wget/curl pour les transferts inter-serveurs.
  • Référence curl : Toutes les options curl, cheatsheet complète avec exemples REST, authentification et diagnostic.
  • Référence wget : Options wget pour le téléchargement récursif, la reprise et la gestion des URLs.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn