Skip to Content
CLIRsync

🔄 Rsync

Synchronisation incrémentale locale et distante, avec exclusions, reprise de transfert et mode daemon.

rsync calcule les différences entre la source et la destination : seuls les blocs modifiés sont envoyés. C’est ce qui le rend rapide même sur des volumes importants.

Syntaxe de base

# Copie locale (équivalent cp -a mais avec les deltas) rsync -avz /source/ /destination/ # Copie vers un serveur distant rsync -avz /source/ user@host:/destination/ # Copie depuis un serveur distant rsync -avz user@host:/source/ /destination/ # Forcer l'utilisation d'un port SSH spécifique rsync -avz -e "ssh -p 2222" /source/ user@host:/destination/

Options essentielles

OptionDescription
-aMode archive : récursif, préserve permissions, timestamps, liens, groupe, owner
-vVerbeux : affiche les fichiers transférés
-zCompression durant le transfert (utile sur lien lent)
--deleteSupprime les fichiers de la destination absents de la source
--excludeIgnore des fichiers/dossiers (pattern)
--dry-runSimule sans modifier — excellent pour vérifier
-PProgress + reprise de transfert
--bwlimit=KBPSLimite de bande passante (ex: --bwlimit=5000 = 5 Mo/s)
--chown=user:groupForcer l’owner/group sur les fichiers créés
--info=progress2Barre de progression (rsync 3.2+)

Schémas source/destination

# Local → Local rsync -av /src/ /dst/ # Local → Distant (SSH, port 22) rsync -av /src/ user@host:/dst/ # Distant → Local rsync -av user@host:/src/ /dst/ # Distant → Distant (via serveur source) rsync -av userA@host1:/src/ userB@host2:/dst/ # Via un socket daemon rsync rsync -av rsync://host:8730/module/src/ /dst/

Le piège de la barre oblique finale

# ⚠️ source/a/ → crée /dst/a/ (contenu dupliqué) rsync -av /src/a/ /dst/ # Résultat : /dst/a/fichier.txt # ⚠️ source/a → crée /dst/a/ (dossier dupliqué) rsync -av /src/a /dst/ # Résultat : /dst/a/a/fichier.txt

Règle : la barre oblique finale sur la source applique le contenu du dossier. Sans barre oblique, rsync recrée le dossier lui-même.

Exclusions

# Exclusion unique rsync -av --exclude='node_modules' /src/ /dst/ # Exclusion multiple rsync -av \ --exclude='.git' \ --exclude='node_modules' \ --exclude='*.log' \ --exclude='*.tmp' \ /src/ /dst/ # Fichier d'exclusion externe (utile pour les listes longues) rsync -av --exclude-from='.rsyncignore' /src/ /dst/

Fichier .rsyncignore :

# Ignorer les fichiers node_modules/ .git/ *.log *.tmp # Ignorer les dossiers entiers build/ dist/ .env

Options avancées

Affichage détaillé des changements (-i)

L’option --itemize-changes (ou -i) affiche un code court (10 à 14 caractères) pour chaque fichier traité. Utile pour comprendre exactement ce qui sera modifié avant d’exécuter une sync destructive.

Format du code (>f.stcuog.Dest par exemple) :

PositionCodesSignification
1>, <, =, !Direction : > vers dest, < depuis src, = identique, ! supprimé
2c, t, M, u, m, s, h, g, x, .Motif de changement : checksum, date, permissions, owner, group, taille, hash, xattr, . identique
3z ou .Compression durant le transfert
4p ou .Version du protocole rsync
5.Toujours un point (réserve)
6S ou DCôté impacté : source ou destination
7O ou N ou .Ancienne ou nouvelle version
8O ou N ou .Ancienne ou nouvelle version
9.Toujours un point (réserve)
10f, d, l, c, b, n, s, i, .Type : fichier, répertoire, symlink, char-device, block-device, fifo, socket, autre

Remarque : la longueur totale du code varie selon les changements détectés. Seuls les changements réels sont codés ; les positions non appliquées prennent la valeur ..

# Exemple de sortie typique : `>f.stcuog.Dest` # signifie : fichier créé sur la destination (`>`), de type fichier (`f`), # avec une taille et un checksum différents (`stcuog`). rsync -avz -i /src/ user@host:/dst/ 2>&1 | head -20

Sync sélective via répertoire de référence (--compare-dest)

Synchronise uniquement les fichiers nouveaux ou modifiés par rapport à un répertoire de référence, sans modifier ce dernier. Pratique pour déployer une version spécifique ou répercuter des changements entre environnements.

# Seulement les fichiers qui ont changé depuis la référence rsync -avz --compare-dest=/reference/ /src/ user@host:/dst/ # Comparer par rapport à un tag git spécifique (local) rsync -avz --compare-dest=/repos/myapp/v1.2.0/ ./dist/ user@staging:/opt/myapp/current/

Crée un lien dur vers les fichiers identiques au snapshot précédent. Permet des backups ou des déploiements multi-version sans doublonner les données inchangées.

# Déploiement avec snapshot versionné (zéro downtime) NEW=/opt/myapp/releases/v1.3.0 PREV=/opt/myapp/releases/v1.2.0 mkdir -p "$NEW" rsync -avz --link-dest="$PREV" \ --exclude='.git' --exclude='node_modules' \ ./dist/ "$NEW/" ln -sfn "$NEW" /opt/myapp/current # Backups incrémentaux sans duplication rsync -avz --link-dest="/backups/latest/" \ /var/lib/mysql/ "/backups/$(date +%Y%m%d%H%M)/" ln -sfn "/backups/$(date +%Y%m%d%H%M)" /backups/latest

Ignorer les timestamps des répertoires (--omit-dir-times)

rsync synchronise aussi les dates de modification des répertoires, ce qui peut provoquer des rebuilds inutiles (make, webpack) si la destination se retrouve avec des timestamps légèrement différents.

# Ne pas toucher aux timestamps des dossiers rsync -avz --omit-dir-times /src/ user@host:/dst/

Ne créer que les fichiers existants (--existing)

Empêche rsync de créer de nouveaux fichiers ou dossiers sur la destination. Utile pour rafraîchir uniquement le contenu existant (ex. : mise à jour incrémentielle de _node_modules_ sans recréer des dossiers vides).

# Mettre à jour uniquement les fichiers déjà présents rsync -av --existing /src/ user@host:/dst/

Mode daemon (serveur rsync)

Côté serveur

# /etc/rsyncd.conf pid file = /var/run/rsyncd.pid log file = /var/log/rsyncd.log [website] path = /var/www/html comment = Site web statique read only = yes list = no uid = www-data gid = www-data
# Démarrer le daemon sudo rsync --daemon --config=/etc/rsyncd.conf # Vérifier l'écoute ss -tlnp | grep 873

Côté client

# Lister les modules disponibles rsync rsync://host/ # Sync depuis un module rsync -av rsync://host/website/ /local/dst/ # Avec authentification (fichier mot de passe côté client) echo "mon_secret" > ~/.rsync_pass chmod 600 ~/.rsync_pass rsync -av rsync://user@host/website/ /local/dst/ --password-file=~/.rsync_pass

systemd (alternatif)

# /etc/systemd/system/rsyncd.service [Unit] Description=Rsync daemon After=network.target [Service] ExecStart=/usr/bin/rsync --daemon --no-detach --config=/etc/rsyncd.conf Restart=on-failure [Install] WantedBy=multi-user.target
sudo systemctl enable --now rsyncd

Cas pratiques

Déploiement staging

# Sync code + exclusions vers staging, suppression des fichiers orphelins rsync -avz --delete \ --exclude='.git' \ --exclude='node_modules' \ --exclude='.env' \ --exclude='*.log' \ ./deploy/ user@staging:/opt/myapp/current/

Backup incrémental quotidien

# Archive avec dates, pas de --delete (on conserve l'historique) DATE=$(date +%Y%m%d) rsync -avz --backup --backup-dir="/backups/${DATE}" \ /var/lib/mysql/ /backups/mysql-latest/

Miroir de assets statiques

# Miroir complet, suppression des fichiers supprimés en source rsync -avz --delete -e ssh \ --exclude='*.DS_Store' \ /srv/assets/ user@cdn:/srv/mirror/assets/

Reprendre un transfert interrompu

# Reprendre automatiquement grâce à -P rsync -avP /gros_fichier/ user@host:/dst/

Alias utiles

# ~/.bashrc alias rsync-dry='rsync -avz --dry-run' alias rsync-deploy='rsync -avz --delete --exclude=".git" --exclude="node_modules"' alias rsync-mirror='rsync -avz --delete'

Dépannage

# Vérifier les permissions sur la destination ls -ld /destination/ ls -la /destination/ # Forcer l'ownership si nécessaire rsync -av --chown=www-data:www-data /src/ user@host:/var/www/ # Sur le serveur rsync, vérifier rsyncd.conf : # "uid" / "gid" / "read only" / "list" # Test en mode verbeux : rsync -avz --info=progress2 user@host:/src/ /dst/ 2>&1 | head