rsync è l’abbreviazione di Remote Sync, ma la sua utilità va ben oltre la semplice sincronizzazione remota. Gestisce file, server, backup o pipeline di dati: è veloce, affidabile, flessibile e, soprattutto, “intelligente”.
La caratteristica che lo rende unico rispetto a strumenti analoghi come cp o scp è il suo algoritmo: invece di copiare l’intero file ogni volta, rsync identifica le sole porzioni modificate e trasferisce esclusivamente quelle garantendo trasferimenti più rapidi, con un minor consumo di banda e una gestione efficiente anche per file di grandi dimensioni.
Iniziamo a capire come funziona l’algoritmo di rsync che opera in quattro fasi fondamentali
- Checksumming: il destinatario divide il file esistente in blocchi di dimensione fissa e calcola per ciascuno due checksum: un rolling checksum debole (Adler-32) e un checksum MD4 più forte
- Invio dei checksum: questi valori vengono inviati alla sorgente
- Ricerca delle differenze: la sorgente scansiona il proprio file cercando corrispondenze con i blocchi del destinatario. I blocchi identici vengono identificati; le porzioni differenti vengono marcate come “delta”
- Trasferimento selettivo: solo i delta vengono trasmessi, assieme alle istruzioni su come ricostruire il file finale
Questo approccio riduce il traffico di rete in modo drastico in scenari di aggiornamento frequente: immaginiamo di sincronizzare un database da 10 GB con una modifica dell’1%, rsync trasferirà circa 100 MB invece di 10 GB.
Su quasi tutte le distribuzioni Linux, rsync è preinstallato o disponibile nei repository ufficiali. Qualora non lo fosse, l’installazione è molto semplice
# Debian / Ubuntu
sudo apt update && sudo apt install rsync
# Red Hat / CentOS / Fedora
sudo dnf install rsync
# macOS (tramite Homebrew)
brew install rsync
# Per verificare la versione installata
rsync --versionLa versione 3.x introduce numerosi miglioramenti rispetto alla 2.x, tra cui supporto per file superiori a 2 GB, migliore gestione delle ACL e incrementi di prestazioni. È consigliabile utilizzare sempre l’ultima versione stabile disponibile.
Sintassi generale
La struttura del comando rsync è
rsync [OPZIONI] SORGENTE DESTINAZIONEDove SORGENTE e DESTINAZIONE possono essere
- Un percorso locale: /home/utente/documenti/
- Un percorso remoto via SSH: utente@server:/percorso/remoto/
- Un modulo rsync daemon: rsync://server/modulo/
Iniziamo subito a chiarire una possibile fonte di confusione, la presenza o assenza dello slash finale sulla directory sorgente. Questo cambia il comportamento in modo significativo
# Copia la directory "foto" e il suo contenuto dentro "backup"
rsync -av /home/carlo/foto /backup/
# Copia solo il CONTENUTO di "foto" dentro "backup"
rsync -av /home/carlo/foto/ /backup/Nel primo caso, il risultato sarà /backup/foto/img001.jpg. Nel secondo caso, il risultato sarà /backup/img001.jpg.
Le opzioni
rsync offre decine di opzioni. Di seguito le più importanti, raggruppate per categoria
Opzioni di modalità e verbosità
| Opzione | Forma lunga | Descrizione |
|---|---|---|
| -v | –verbose | Output dettagliato delle operazioni |
| -q | –quiet | Sopprime l’output (ideale per cron job) |
| -n | –dry-run | Simula l’esecuzione senza trasferire nulla |
| –progress | Mostra il progresso durante il trasferimento | |
| –stats | Mostra statistiche dettagliate al termine | |
| –info=FLAGS | Controllo granulare dell’output informativo |
Opzioni di copia
| Opzione | Forma lunga | Descrizione |
|---|---|---|
| -r | –recursive | Ricorsivo: include le sottodirectory |
| -a | –archive | Modalità archivio: equivale a -rlptgoD |
| -l | –links | Preserva i symlink come symlink |
| -p | –perms | Preserva i permessi |
| -t | –times | Preserva i timestamp di modifica |
| -g | –group | Preserva il gruppo proprietario |
| -o | –owner | Preserva il proprietario (richiede l’esecuzione come root) |
| -D | Preserva device file e file speciali | |
| -H | –hard-links | Preserva gli hard link |
| -A | –acls | Preserva gli ACL POSIX |
| -X | –xattrs | Preserva gli attributi estesi |
| -z | –compress | Comprime i dati durante il trasferimento |
L’opzione -a è probabilmente la più comune nei comandi rsync. Attiva automaticamente: -r (ricorsivo), -l (symlink), -p(permessi), -t (timestamp), -g (gruppo), -o (owner), -D (device files). È la scelta ideale per backup e sincronizzazioni complete.
Opzioni di sincronizzazione e controllo
| Opzione | Forma lunga | Descrizione |
|---|---|---|
| –delete | Elimina dalla destinazione i file non presenti nella sorgente | |
| –delete-before | Elimina prima del trasferimento | |
| –delete-after | Elimina dopo il trasferimento | |
| –delete-excluded | Elimina anche i file esclusi dalla destinazione | |
| –ignore-existing | Non sovrascrive file già presenti nella destinazione | |
| -u | –update | Salta file più recenti nella destinazione |
| -c | –checksum | Usa checksum invece dei timestamp per confrontare |
| –size-only | Confronta solo per dimensione | |
| -b | –backup | Crea backup dei file sovrascritti |
| –backup-dir=DIR | Specifica directory per i backup | |
| –suffix=SUFFIX | Suffisso per i file di backup (default: ~) |
Opzioni di rete e performance
| Opzione | Forma lunga | Descrizione |
|---|---|---|
| -e | –rsh=COMMAND | Specifica la shell remota (es. SSH) |
| –bwlimit=Kbps | Limita la banda utilizzata | |
| –partial | Mantieni i file parzialmente trasferiti | |
| –partial-dir=DIR | Directory per file parziali | |
| –inplace | Aggiorna il file in-place senza copia temporanea | |
| –append | Aggiunge dati a file esistenti | |
| –timeout=SEC | Timeout I/O in secondi |
Esempi pratici
Dopo aver visto le varie opzioni del comando rsync, analizziamo alcuni esempi di comandi.
rsync -av /home/carlo/documenti/ /media/usb/backup-documenti/Copia il contenuto di documenti nella directory backup-documenti sul dispositivo USB, preservando tutti i metadati e mostrando ogni file copiato
rsync -avn --delete /home/carlo/documenti/ /media/usb/backup-documenti/L’opzione -n (dry-run) è fondamentale: mostra esattamente cosa verrebbe fatto senza toccare nulla. Va usata sempre prima di operazioni critiche, specialmente quando si usa –delete
rsync -av --delete /home/carlo/documenti/ /media/usb/backup-documenti/Con –delete, la destinazione diventa una copia identica della sorgente: i file rimossi dalla sorgente vengono eliminati anche dalla destinazione
rsync -av --progress /home/carlo/video/ /media/nas/video/Utile per trasferimenti lunghi: mostra la percentuale di completamento, la velocità di trasferimento e il tempo rimanente per ogni file
rsync -av --stats /home/carlo/foto/ /backup/foto/Al termine del trasferimento, –stats fornisce un riepilogo con numero di file trasferiti, byte totali, byte effettivamente inviati (grazie alla compressione delta), velocità media e tempo impiegato
# Da locale a remoto
rsync -avz /percorso/locale/ utente@server.esempio.com:/percorso/remoto/
# Da remoto a locale
rsync -avz utente@server.esempio.com:/percorso/remoto/ /percorso/locale/Una delle feature più potenti di rsync è la capacità di operare su connessioni SSH, rendendo possibile sincronizzare dati tra macchine remote in modo sicuro. L’opzione -z aggiunge la compressione, particolarmente vantaggiosa su connessioni lente
rsync -avz -e "ssh -p 2222" /dati/ utente@server.esempio.com:/backup/dati/Specifica una porta SSH non standard
rsync -avz -e "ssh -i ~/.ssh/chiave_privata -p 22" \
/dati/ utente@server.esempio.com:/backup/dati/Usa una chiave ssh per il trasferimento che rende molto più sicuro lo script
# Esclude una singola directory, es. tmp
rsync -av --exclude='tmp' /progetto/ /backup/progetto/
# Esclude più pattern
rsync -av \
--exclude='*.log' \
--exclude='*.tmp' \
--exclude='.git' \
--exclude='__pycache__' \
/progetto/ /backup/progetto/Esegue un backup selettivo escludendo un’intera directory “tmp” oppure una serie di directory o file con le estensioni specificate. Per scenari complessi, è pratico creare un file dedicato alle esclusioni
# Crea il file exclude-list.txt
cat > ~/exclude-list.txt << 'EOF'
*.log
*.tmp
*.cache
.git/
node_modules/
__pycache__/
.DS_Store
Thumbs.db
*.swp
/tmp/
EOF
# Usa il file
rsync -av --exclude-from='~/exclude-list.txt' /progetto/ /backup/progetto/rsync applica le regole di filtro nell’ordine in cui compaiono, la prima regola che corrisponde viene applicata. Questo è fondamentale per costruire filtri precisi
# Copia solo i file .php e .html, escludendo tutto il resto
rsync -av \
--include='*/' \
--include='*.php' \
--include='*.html' \
--exclude='*' \
/sito-web/ /backup/sito-web/In questo esempio, sono incluse tutte le directory (*/) per permettere la navigazione ricorsiva, include i file .php e .html, esclude tutto il resto. L’ordine è fondamentale, invertirlo produce risultati completamente diversi
# Esclude /progetto/logs/ ma non /progetto/src/logs/
rsync -av --exclude='/logs/' /progetto/ /backup/progetto/
# Esclude qualsiasi directory "logs" a qualsiasi livello
rsync -av --exclude='logs/' /progetto/ /backup/progetto/La barra iniziale nell’esclusione ancora il pattern alla radice della sorgente
rsync -av --backup --backup-dir=/backup/modificati-$(date +%Y%m%d) --delete /dati/ /backup/corrente/Ad ogni esecuzione, i file modificati o eliminati vengono spostati in una directory con la data corrente. Si riesce quindi a mantenere una copia corrente sempre aggiornata più uno storico delle versioni precedenti
# Confronta sorgente e backup usando checksum (lento ma accurato)
rsync -avnc --delete /dati/ /backup/dati/L’opzione -c (checksum) ignora timestamp e dimensioni, confrontando il contenuto effettivo dei file. Utile per verifiche periodiche dell’integrità
# Limita a 10 MB/s (il valore è in KB/s)
rsync -avz --bwlimit=10240 /dati/ utente@server.esempio.com:/backup/Permette di gestire la banda utilizzata durante il trasferimento evitando, soprattutto su connessioni non veloci, di saturarla
# Trasferisce 4 elementi in parallelo
ls /sorgente/ | parallel -j4 \
rsync -av /sorgente/{} utente@server.esempio.com:/destinazione/{}Parallelizza i trasferimenti utilizzando parallel, molto utilizzato nel caso di directory con migliaia di file piccoli per ridurre il tempo di trasferimento
# Prima sincronizzazione: usa tar per l'invio iniziale
tar czf - /dati/ | ssh utente@server.esempio.com "tar xzf - -C /backup/"
# Aggiornamenti successivi: usa rsync per i delta
rsync -av --delete /dati/ utente@server.esempio.com:/backup/dati/Un altro modo per gestire la sincronizzazione di directory con migliaia di file è combinarne l’utilizzo con tar con cui fare un trasferimento iniziale e poi con rsync gestire la sincronizzazione delle differenze
#!/bin/bash
# Sincronizza i dump giornalieri del database
DUMP_DIR="/var/backups/mysql"
REMOTE="server.esempio.com:/archivio/mysql"
# Genera dump
mysqldump --all-databases | gzip > "$DUMP_DIR/all-databases-$(date +%Y%m%d).sql.gz"
# Rimuovi dump più vecchi di 7 giorni localmente
find "$DUMP_DIR" -name "*.sql.gz" -mtime +7 -delete
# Sincronizza con il server di backup remoto
rsync -avz --delete \
--stats \
"$DUMP_DIR/" \
"utente@$REMOTE/"In questo piccolo script di esempio vengono sincronizzati i dump dei database su un server remoto, mantenendo i due archivi allineati
