Aller au contenu
English
Compte : non connecté, synchronisation possible Mon apprentissage
Selectionner le thème
English

Gérer vos buckets S3 avec s3cmd

21 min de lecture
Améliorer cette page

S3cmd est un outil en ligne de commande pour transférer, synchroniser et gérer vos données sur Amazon S3 et tout stockage compatible (MinIO, Outscale OOS, Scaleway, DigitalOcean Spaces...). Avec une seule commande, vous pouvez uploader des fichiers, synchroniser des dossiers, gérer les ACL et automatiser vos sauvegardes.

Principales fonctionnalités :

  • put/get : transférer des fichiers vers/depuis S3
  • sync : synchroniser un dossier local avec un bucket (incrémental)
  • mb/rb : créer et supprimer des buckets
  • ls : lister buckets et objets
  • cp/mv/del : copier, déplacer, supprimer des objets

Via pipx (recommandé pour avoir la dernière version). Les distributions récentes refusent pip install en dehors d'un environnement virtuel (PEP 668, erreur externally-managed-environment) : pipx isole l'outil dans son propre environnement et le rend disponible dans le PATH :

Fenêtre de terminal
sudo apt install pipx # Debian/Ubuntu ; sur Fedora : sudo dnf install pipx
pipx install s3cmd==2.4.0

Ou via le gestionnaire de paquets (version potentiellement plus ancienne) :

Fenêtre de terminal
# Debian/Ubuntu
sudo apt install s3cmd
# Fedora/RHEL
sudo dnf install s3cmd

Vérifiez l'installation :

Fenêtre de terminal
s3cmd --version
Sortie attendue
s3cmd version 2.4.0

Pour tester les commandes de ce guide sans frais, déployons un stockage compatible S3 en local, avec Docker. MinIO ne publie plus d'image communautaire récupérable : au 9 octobre 2026, minio/minio sur Docker Hub et quay.io/minio/minio ne se téléchargent plus. Ce guide utilise donc RustFS, un autre stockage compatible S3. RustFS est publié en version stable (1.0.1) ; ici, il ne sert que de banc d'essai local. Vous pourrez ensuite adapter la configuration à votre provider (AWS S3, Outscale, Scaleway...).

  1. Lancez RustFS sur le port 9000, limité à 127.0.0.1 :

    Fenêtre de terminal
    export AWS_ACCESS_KEY_ID=demo-local-access
    export AWS_SECRET_ACCESS_KEY=demo-local-secret-key
    docker run -d --name rustfs -p 127.0.0.1:9000:9000 \
    -e RUSTFS_ACCESS_KEY="$AWS_ACCESS_KEY_ID" \
    -e RUSTFS_SECRET_KEY="$AWS_SECRET_ACCESS_KEY" \
    -e RUSTFS_VOLUMES=/data \
    -v rustfs-data:/data \
    rustfs/rustfs:1.0.1@sha256:1803faef57627e2d9c2e7d89d655d712ddded5389040054987163043fecb6a3c

    Les deux valeurs demo-local-* sont des valeurs de démonstration, valables uniquement pour ce conteneur local lié à 127.0.0.1. Ne les réutilisez jamais sur un vrai stockage.

  2. Vérifiez qu'il répond :

    Fenêtre de terminal
    curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:9000/health

    La commande doit afficher 200. Pour tout supprimer en fin de test : docker rm -fv rustfs && docker volume rm rustfs-data.

s3cmd lit ses paramètres dans un unique fichier, ~/.s3cfg. Deux réglages y décident de tout le reste : host_base, qui désigne le service visé, et signature_v2, qui doit correspondre à ce que ce service accepte. Une erreur sur l'un des deux se manifeste par un refus d'authentification, jamais par un message explicite sur la cause.

Lancez l'assistant de configuration :

Fenêtre de terminal
s3cmd --configure

L'assistant vous demande :

  • Access Key : votre clé d'accès (ex: demo-local-access pour le banc RustFS ci-dessus)
  • Secret Key : votre clé secrète
  • Default Region : région par défaut (ex: us-east-1)
  • S3 Endpoint : URL du service S3 (ex: 127.0.0.1:9000 pour le banc RustFS ci-dessus)

Les valeurs par défaut de l'assistant visent AWS S3 et ne conviennent pas au banc RustFS. Trois réponses doivent changer : HTTPS (Use HTTPS protocol) à No, car RustFS écoute en HTTP ; le style d'adressage (DNS-style bucket+hostname:port template) à 127.0.0.1:9000, c'est-à-dire sans %(bucket)s, pour que le nom du bucket reste dans le chemin ; et la région (Default Region) à us-east-1, que RustFS exige. L'assistant laisse la signature v4 par défaut (signature_v2 = False), ce qui convient. Les mêmes réglages sont détaillés dans la configuration manuelle ci-dessous.

Pour RustFS ou un stockage compatible, créez directement le fichier ~/.s3cfg. Les clés n'y figurent pas : à défaut, s3cmd lit AWS_ACCESS_KEY_ID et AWS_SECRET_ACCESS_KEY, exportées lors du lancement de RustFS.

~/.s3cfg
[default]
host_base = 127.0.0.1:9000
host_bucket = 127.0.0.1:9000
use_https = False
signature_v2 = False
bucket_location = us-east-1

Deux réglages comptent avec RustFS. host_bucket doit répéter l'hôte sans %(bucket)s : s3cmd place alors le nom du bucket dans le chemin de l'URL. Avec le gabarit par défaut d'AWS, s3cmd place le nom du bucket dans le nom d'hôte et RustFS répond 403 (InvalidAccessKeyId), un message trompeur ; avec 127.0.0.1:9000/%(bucket)s, ls passe mais mb et put échouent en SignatureDoesNotMatch. Et bucket_location = us-east-1 est nécessaire : la valeur par défaut US provoque 400 (InvalidRequest): invalid credential region. Gardez la signature v4 : en signature_v2 = True, RustFS 1.0.1 répond 400 (InvalidRequest): invalid x-amz-date dès la première requête.

Seules quelques lignes changent d'un fournisseur à l'autre : le point d'accès, le gabarit de nom de bucket, le chiffrement du transport (use_https) et parfois la version de signature. Le reste du fichier est identique, ce qui explique qu'un même script fonctionne partout avec un simple changement de profil.

~/.s3cfg
[default]
access_key = VOTRE_ACCESS_KEY
secret_key = VOTRE_SECRET_KEY
host_base = s3.eu-west-3.amazonaws.com
host_bucket = %(bucket)s.s3.eu-west-3.amazonaws.com
use_https = True
signature_v2 = False

Adaptez la région dans le point d'accès : eu-west-3 désigne Paris.

Un bucket est le conteneur de premier niveau du stockage objet. Son nom est unique par service et entre dans l'URL d'accès, ce qui interdit les majuscules et les caractères accentués. Ces quatre commandes couvrent son cycle de vie complet.

mb (make bucket) crée le bucket ; choisissez un nom conforme aux règles ci-dessus.

Fenêtre de terminal
s3cmd mb s3://mon-bucket
Sortie
Bucket 's3://mon-bucket/' created

Sans argument, ls liste les buckets avec leur date de création ; avec un chemin, il liste leur contenu.

Fenêtre de terminal
s3cmd ls
Sortie
2026-01-23 14:18 s3://mon-bucket
2026-01-23 13:39 s3://autre-bucket

info révèle les réglages que les autres commandes ne montrent pas : région, versioning, politique et CORS.

Fenêtre de terminal
s3cmd info s3://mon-bucket
Sortie
s3://mon-bucket/ (bucket):
Location: us-east-1
Payer: BucketOwner
Ownership: none
Versioning:none
Expiration rule: none
Block Public Access: none
Policy: none
CORS: none
ACL: floci: FULL_CONTROL

Cette sortie provient de s3cmd 2.4.0 face à un autre stockage S3 local (Floci) : le nom du propriétaire de l'ACL dépend du service. Face au banc RustFS de ce guide, info aboutit aussi, mais il patiente environ 45 secondes : RustFS répond 500 (NoSuchPublicAccessBlockConfiguration) à la requête sur le blocage d'accès public, et s3cmd la retente cinq fois avec des WARNING: Retrying failed request avant d'afficher Block Public Access: none. Ce n'est pas une panne, attendez la fin.

La commande échoue tant que le bucket contient un seul objet ; il faut le vider d'abord.

Pour ne pas détruire le bucket mon-bucket dont les sections suivantes ont besoin, l'exemple utilise un bucket jetable :

Fenêtre de terminal
s3cmd mb s3://bucket-jetable
# Le bucket doit être vide
s3cmd rb s3://bucket-jetable
Sortie
Bucket 's3://bucket-jetable/' created
Bucket 's3://bucket-jetable/' removed

put et get transfèrent des objets un par un ou par lots. Le point d'attention est la barre finale dans la destination : s3://bucket/dossier/ place le fichier dans le dossier, alors que s3://bucket/dossier le renomme. L'option --recursive est indispensable dès qu'une arborescence est en jeu.

La progression affichée indique le débit réel : c'est le premier indicateur à regarder quand un transfert paraît lent.

Fenêtre de terminal
s3cmd put rapport.txt s3://mon-bucket/
Sortie
upload: 'rapport.txt' -> 's3://mon-bucket/rapport.txt' [1 of 1]
29 of 29 100% in 0s 6.47 KB/s done

Le shell développe le motif avant l'appel : c'est lui qui décide des fichiers envoyés, pas s3cmd.

Fenêtre de terminal
s3cmd put *.pdf s3://mon-bucket/documents/

Les sorties des sections suivantes supposent que vous n'avez pas exécuté cet exemple : il ajouterait des objets documents/*.pdf dans le bucket.

--recursive est obligatoire sur un dossier, sans quoi la commande refuse de traiter le répertoire.

Fenêtre de terminal
s3cmd put --recursive mon-dossier/ s3://mon-bucket/backup/

get refuse d'écraser un fichier local existant, comportement voulu qui évite la perte de données involontaire.

Fenêtre de terminal
s3cmd get s3://mon-bucket/rapport.txt ./
Sortie
download: 's3://mon-bucket/rapport.txt' -> './rapport.txt' [1 of 1]
29 of 29 100% in 0s 32.93 KB/s done

La barre finale sur la source détermine si l'arborescence est recréée telle quelle dans la destination.

Fenêtre de terminal
mkdir restore
s3cmd get --recursive s3://mon-bucket/backup/ ./restore/
Sortie
download: 's3://mon-bucket/backup/documents/notes.md' -> './restore/documents/notes.md' (25 bytes in 0.0 seconds, 14.55 KB/s)
download: 's3://mon-bucket/backup/documents/rapport.txt' -> './restore/documents/rapport.txt' (29 bytes in 0.0 seconds, 20.98 KB/s)
download: 's3://mon-bucket/backup/photos/vacances.jpg' -> './restore/photos/vacances.jpg' (15 bytes in 0.0 seconds, 1861.38 B/s)

Le dossier de destination doit exister. Si ./restore/ n'a pas été créé, s3cmd 2.4.0 refuse tout téléchargement multiple avec ERROR: Parameter problem: Destination must be a directory or stdout when downloading multiple sources. (code de sortie 64) et n'écrit rien. Le préfixe backup/ donné en source n'est pas recréé : les sous-dossiers documents/ et photos/ apparaissent directement dans restore/.

Le stockage objet n'a pas de vrais répertoires : la hiérarchie que vous voyez est une convention de nommage sur les clés. C'est pourquoi ls sans --recursive n'affiche que le premier niveau, en regroupant le reste sous des préfixes communs.

Sans --recursive, seul le premier niveau apparaît : les clés plus profondes sont regroupées sous leur préfixe commun.

Fenêtre de terminal
s3cmd ls s3://mon-bucket/
Sortie
DIR s3://mon-bucket/backup/
2026-10-09 21:28 29 s3://mon-bucket/rapport.txt

La ligne DIR est le préfixe commun backup/ : tout ce qui se trouve dessous est regroupé sur une seule ligne, sans date ni taille, et seuls les objets du premier niveau gardent leur ligne propre.

Cette forme affiche toutes les clés, à plat. C'est celle à utiliser pour compter des objets ou chercher un chemin précis.

Fenêtre de terminal
s3cmd ls -r s3://mon-bucket/
Sortie
2026-10-09 21:28 25 s3://mon-bucket/backup/documents/notes.md
2026-10-09 21:28 29 s3://mon-bucket/backup/documents/rapport.txt
2026-10-09 21:28 15 s3://mon-bucket/backup/photos/vacances.jpg
2026-10-09 21:28 29 s3://mon-bucket/rapport.txt

Quatre objets : c'est le nombre que du renvoie juste après.

du renvoie la taille cumulée et le nombre d'objets, les deux valeurs qui déterminent la facturation.

Fenêtre de terminal
s3cmd du s3://mon-bucket/
Sortie
98 4 objects s3://mon-bucket/

Ces opérations s'exécutent côté serveur : les données ne transitent pas par votre machine, ce qui rend la copie d'un gros objet quasi instantanée. La suppression, elle, est définitive et sans confirmation sur un bucket dépourvu de versioning.

La mention remote copy dans la sortie confirme que l'opération s'est faite côté serveur, sans transfert par votre machine.

Fenêtre de terminal
s3cmd cp s3://mon-bucket/rapport.txt s3://mon-bucket/archives/rapport.txt
Sortie
remote copy: 's3://mon-bucket/rapport.txt' -> 's3://mon-bucket/archives/rapport.txt' [1 of 1]

Les deux buckets doivent appartenir au même service ; entre deux fournisseurs, il faut télécharger puis renvoyer.

Fenêtre de terminal
s3cmd cp s3://source-bucket/fichier.txt s3://dest-bucket/fichier.txt

mv enchaîne une copie puis une suppression : en cas d'interruption, l'objet peut exister aux deux emplacements.

Fenêtre de terminal
s3cmd mv s3://mon-bucket/ancien.txt s3://mon-bucket/nouveau.txt

La suppression est immédiate et sans confirmation, et définitive si le versioning n'est pas activé sur le bucket.

Fenêtre de terminal
s3cmd del s3://mon-bucket/fichier.txt
Sortie
delete: 's3://mon-bucket/fichier.txt'

--force supprime tout le contenu sans demander : c'est la commande la plus dangereuse de cette page.

Fenêtre de terminal
s3cmd del s3://mon-bucket/ --recursive --force
Sortie
delete: 's3://mon-bucket/archives/rapport.txt'
delete: 's3://mon-bucket/backup/documents/notes.md'
delete: 's3://mon-bucket/backup/documents/rapport.txt'
delete: 's3://mon-bucket/backup/photos/vacances.jpg'
delete: 's3://mon-bucket/rapport.txt'

--recursive seul ne suffit pas. Sans --force, s3cmd refuse et ne supprime rien : ERROR: Parameter problem: Please use --force to delete ALL contents of s3://mon-bucket/ (code de sortie 64).

La synchronisation est la fonctionnalité la plus puissante de s3cmd. Elle compare les fichiers et ne transfère que les modifications.

sync compare par défaut la taille et la somme MD5 avant d'agir (--no-check-md5 limite la comparaison à la taille), et ne transfère que les fichiers réellement modifiés, ce qui en fait une copie incrémentale.

Fenêtre de terminal
s3cmd sync mon-dossier/ s3://mon-bucket/backup/
Sortie
upload: 'mon-dossier/documents/notes.md' -> 's3://mon-bucket/backup/documents/notes.md' [1 of 3]
25 of 25 100% in 0s 4.36 KB/s done
upload: 'mon-dossier/documents/rapport.txt' -> 's3://mon-bucket/backup/documents/rapport.txt' [2 of 3]
29 of 29 100% in 0s 9.71 KB/s done
upload: 'mon-dossier/photos/vacances.jpg' -> 's3://mon-bucket/backup/photos/vacances.jpg' [3 of 3]
15 of 15 100% in 0s 5.25 KB/s done
Done. Uploaded 69 bytes in 1.0 seconds, 69.00 B/s.

Le sens s'inverse en échangeant simplement source et destination : c'est la commande de restauration.

Fenêtre de terminal
s3cmd sync s3://mon-bucket/backup/ ./restore/
Sortie
download: 's3://mon-bucket/backup/documents/notes.md' -> './restore/documents/notes.md' [1 of 3]
25 of 25 100% in 0s 22.01 KB/s done
download: 's3://mon-bucket/backup/documents/rapport.txt' -> './restore/documents/rapport.txt' [2 of 3]
29 of 29 100% in 0s 37.31 KB/s done
download: 's3://mon-bucket/backup/photos/vacances.jpg' -> './restore/photos/vacances.jpg' [3 of 3]
15 of 15 100% in 0s 21.96 KB/s done
Done. Downloaded 69 bytes in 1.0 seconds, 69.00 B/s.

Les motifs s'appliquent au chemin relatif de chaque fichier, et plusieurs --exclude peuvent être cumulés.

Fenêtre de terminal
s3cmd sync mon-dossier/ s3://mon-bucket/backup/ --exclude '*.tmp' --exclude '*.log'

--delete-removed aligne la destination sur la source : ce qui a disparu localement est effacé côté serveur.

Fenêtre de terminal
s3cmd sync mon-dossier/ s3://mon-bucket/backup/ --delete-removed

Ces commandes dépendent du service en face : le versioning, les tags et les URL signées font partie de l'API S3, mais toutes les implémentations compatibles ne les exposent pas. Vérifiez leur prise en charge avant de bâtir une procédure dessus.

Une fois activé, le versioning conserve chaque révision d'un objet : la suppression pose alors un marqueur au lieu d'effacer, et l'espace facturé continue de croître.

Fenêtre de terminal
s3cmd setversioning s3://mon-bucket enable

Les tags servent à ventiler les coûts et à cibler des règles de cycle de vie sans toucher au nom des objets.

Fenêtre de terminal
# Ajouter des tags : un seul argument, les paires séparées par &
s3cmd settagging s3://mon-bucket/fichier.txt "projet=devops&env=prod"
# Voir les tags
s3cmd gettagging s3://mon-bucket/fichier.txt
# Supprimer les tags
s3cmd deltagging s3://mon-bucket/fichier.txt

La liste de tags tient dans un seul argument, de la forme clé=valeur&clé=valeur. Avec deux arguments séparés ("projet=devops" "env=prod"), s3cmd 2.4.0 ne signale aucune erreur mais ne retient que le premier : gettagging n'affiche alors que projet. Ces commandes aboutissent sur le banc RustFS 1.0.1.

L'URL donne un accès temporaire et sans authentification à un objet privé, jusqu'à l'expiration indiquée.

Fenêtre de terminal
s3cmd signurl s3://mon-bucket/fichier.txt +3600

Cette commande génère une URL temporaire valide 1 heure (3600 secondes).

Rendre un objet public le laisse lisible par quiconque connaît son URL. Si la journalisation des accès (access logs) est activée sur le bucket, ces requêtes anonymes y sont enregistrées aussi, avec un demandeur vide (-) ; mais elle est désactivée par défaut, et ce journal ne dit pas qui se cache derrière l'anonyme.

Fenêtre de terminal
# Rendre un objet public
s3cmd setacl s3://mon-bucket/fichier.txt --acl-public
# Rendre privé
s3cmd setacl s3://mon-bucket/fichier.txt --acl-private

Le banc RustFS 1.0.1 accepte --acl-private mais refuse --acl-public avec 501 (NotImplemented): ACL XML grants are not supported. Cette limite vient du service, pas de s3cmd.

Ce tableau sert à résoudre les erreurs courantes de s3cmd. Repérez le message d'erreur dans la première colonne, vérifiez la cause probable, puis appliquez la solution proposée, souvent un réglage du fichier de configuration.

ProblèmeCause probableSolution
SignatureDoesNotMatchVersion de signature refusée par le service, ou clés incorrectesVérifiez d'abord les clés et host_base. Avec RustFS, gardez signature_v2 = False et ajoutez bucket_location = us-east-1 (la signature v2 y donne invalid x-amz-date) ; AWS S3 n'accepte plus la signature v2 pour les nouveaux buckets (et jamais dans les régions récentes)
Name or service not knownhost_bucket incorrectPour un stockage en mode chemin (RustFS), mettez host_bucket à la même valeur que host_base, sans %(bucket)s ; le suffixe /%(bucket)s fait échouer les écritures en SignatureDoesNotMatch
400 (InvalidRequest): invalid credential regionRégion par défaut US de s3cmd, que RustFS refuseAjoutez bucket_location = us-east-1 dans ~/.s3cfg
Access DeniedCredentials incorrectsVérifiez access_key et secret_key
Bucket already existsNom de bucket prisChoisissez un nom unique
409 (BucketNotEmpty)Bucket non vide (sur un bucket versionné, les anciennes versions comptent)Videz avec s3cmd del s3://bucket/ --recursive --force, puis s3cmd rb s3://bucket
  • Un seul outil pour tout : s3cmd gère upload, download, sync, ACL, versioning.
  • Synchronisation incrémentale : seuls les fichiers modifiés sont transférés.
  • Compatible S3 : AWS, Outscale, Scaleway, DigitalOcean, RustFS... à condition de régler host_base, host_bucket, signature_v2 et, selon le service, bucket_location.
  • --dry-run toujours : prévisualisez les sync/delete avant de les exécuter.
  • Configuration par fichier : ~/.s3cfg évite de répéter les credentials.

Ce projet vous est utile ?

Les guides, formations, quiz et labs restent gratuits. Si vous les utilisez régulièrement, vous pouvez contribuer à leur maintenance et à leur développement.

Devenir membre de soutien (nouvel onglet) Soutenir une fois (nouvel onglet) En savoir plus

Suivez aussi le projet sur LinkedIn