rsync copia file e cartelle come cp, ma in modo più intelligente: trasferisce solo ciò che è cambiato, può lavorare tra computer diversi attraverso SSH e permette di mantenere due cartelle identiche. È lo strumento classico per backup, migrazioni di siti e copie di grandi quantità di dati.
Cos'è
rsync sta per remote synchronization. Il suo punto di forza è l'algoritmo che confronta origine e destinazione e invia soltanto le differenze: la prima copia trasferisce tutto, le successive molto meno. Funziona in locale (da una cartella a un'altra) e in rete, di solito attraverso ssh. Su Debian e Ubuntu è nel pacchetto rsync: sudo apt install rsync. Per i trasferimenti in rete deve essere installato su entrambe le macchine.
Cosa fa
Confronta i file dell'origine con quelli della destinazione (per impostazione predefinita guarda dimensione e data di modifica), copia quelli nuovi o modificati e, se glielo chiedi, può anche cancellare dalla destinazione ciò che nell'origine non esiste più. Può conservare permessi, proprietari, date e collegamenti simbolici, riprendere un trasferimento interrotto e mostrare cosa farebbe senza toccare nulla.
Come si usa
$ rsync [opzioni] ORIGINE DESTINAZIONEL'origine o la destinazione possono essere remote, con la forma utente@host:percorso, la stessa di scp. Gli indirizzi e i nomi negli esempi (server.example.org, l'utente enzo, i percorsi) sono d'esempio: sostituiscili con i tuoi.
Esempio 1: la forma base, in locale
$ ls progetto/
index.html stile.css immagini
$ rsync -av progetto/ copia/
sending incremental file list
created directory copia
./
index.html
stile.css
immagini/
immagini/logo.png
sent 48.317 bytes received 118 bytes 96.870,00 bytes/sec
total size is 47.985 speedup is 0,99Le opzioni -a (archive) e -v (verbose) sono la combinazione di base: -a copia le cartelle in modo ricorsivo e conserva permessi, proprietari, date e collegamenti simbolici; -v elenca i file trasferiti. Riga per riga: l'elenco dei file copiati, poi i byte inviati e la dimensione totale.
Esempio 2: la barra finale cambia tutto
$ rsync -av progetto/ copia/
$ ls copia/
index.html stile.css immagini
$ rsync -av progetto copia/
$ ls copia/
progettoQuesto è il dettaglio più importante di rsync. Con la barra finale sull'origine (progetto/) si copia il contenuto della cartella; senza barra (progetto) si copia la cartella stessa, che finisce dentro la destinazione. La barra sulla destinazione, invece, non cambia nulla. Nel dubbio, prova prima con -n (vedi l'esempio successivo).
Esempio 3: simulare prima con -n
$ rsync -avn progetto/ copia/
sending incremental file list
index.html
sent 83 bytes received 19 bytes 204,00 bytes/sec
total size is 47.985 speedup is 470,44 (DRY RUN)Con -n (dry run) rsync mostra cosa farebbe senza copiare né cancellare niente. La scritta (DRY RUN) alla fine conferma che è solo una prova. È un'abitudine da prendere ogni volta che si usano percorsi nuovi o opzioni come --delete.
Esempio 4: la seconda volta si copia solo il cambiato
$ echo "nuova riga" >> progetto/index.html
$ rsync -av progetto/ copia/
sending incremental file list
index.html
sent 1.152 bytes received 47 bytes 2.398,00 bytes/sec
total size is 48.010 speedup is 40,04Ripetendo il comando vengono trasferiti solo i file modificati: qui index.html. Con file grandi, rsync invia addirittura soltanto le parti diverse del file. Se non è cambiato niente, l'elenco è vuoto e il comando termina in un attimo.
Esempio 5: copiare verso un server (e da un server)
$ rsync -avz progetto/ enzo@server.example.org:/home/enzo/progetto/
$ rsync -avz enzo@server.example.org:/var/www/sito/ ./sito-locale/
$ rsync -avz -e "ssh -p 2222" progetto/ web:/home/enzo/progetto/Con la forma utente@host:percorso rsync si collega via SSH (con le stesse chiavi e lo stesso file ~/.ssh/config di ssh: quindi funzionano anche i nomi brevi, come web). L'opzione -z comprime i dati durante il trasferimento, utile su connessioni lente. Con -e si indica il comando da usare per il collegamento, per esempio per cambiare la porta.
Esempio 6: avanzamento e riprese con -P
$ rsync -avP film.mkv enzo@server.example.org:/home/enzo/video/
sending incremental file list
film.mkv
412.352.512 27% 38,15MB/s 0:00:28-P è la scorciatoia di --progress --partial: mostra l'avanzamento di ogni file e conserva i file parziali. Se il trasferimento si interrompe, rilanciando lo stesso comando riprende dal punto in cui era arrivato, invece di ricominciare da capo.
Esempio 7: tenere due cartelle identiche con --delete
$ rm progetto/vecchio.txt
$ rsync -av --delete progetto/ copia/
sending incremental file list
deleting vecchio.txt
sent 67 bytes received 12 bytes 158,00 bytes/sec
total size is 47.985 speedup is 607,41Di norma rsync non cancella niente dalla destinazione. Con --delete elimina i file che nell'origine non esistono più, quindi la destinazione diventa una copia esatta. È utile per gli specchi (mirror) di un sito o di una cartella, ma è anche l'opzione più rischiosa (vedi più sotto): prova sempre prima con -n.
Esempio 8: escludere file e cartelle
$ rsync -av --exclude='*.tmp' --exclude='cache/' --exclude='.git/' progetto/ copia/
$ rsync -av --exclude-from=esclusioni.txt progetto/ copia/
$ cat esclusioni.txt
*.tmp
cache/
node_modules/Con --exclude si saltano file o cartelle che corrispondono a un modello; con --exclude-from i modelli si leggono da un file, uno per riga. I modelli si riferiscono ai percorsi relativi all'origine. Un modello come /cache/ (con la barra iniziale) esclude solo quello nella cartella principale, mentre cache/ esclude qualsiasi cartella con quel nome. Esiste anche --include, per fare eccezioni, ma l'ordine delle regole conta: vince la prima che corrisponde.
Esempio 9: backup di un sito (un caso reale)
$ rsync -avz --delete \
--exclude='sites/default/files/php/' \
--exclude='sites/default/files/css/' \
--exclude='sites/default/files/js/' \
enzo@server.example.org:/var/www/sito/ /backup/sito/Qui si scarica in locale una copia del sito web, escludendo le cartelle di cache che si rigenerano da sole (nell'esempio, quelle tipiche di Drupal). La prima esecuzione richiede tempo, le successive solo pochi secondi. I backup del solo codice e dei file non bastano per un sito con database: serve anche l'esportazione di quest'ultimo.
Esempio 10: backup con versioni, a spazio quasi costante
$ OGGI=$(date +%F)
$ rsync -a --delete --link-dest=/backup/ultimo /home/enzo/documenti/ /backup/$OGGI/
$ ln -sfn /backup/$OGGI /backup/ultimoCon --link-dest i file che non sono cambiati rispetto al backup precedente non vengono copiati di nuovo: rsync crea un collegamento fisico (hard link, visto nell'articolo su ln) al file già presente. Ogni cartella datata sembra un backup completo, ma occupa solo lo spazio di ciò che è cambiato. L'ultimo comando aggiorna il collegamento simbolico ultimo perché punti all'ultimo backup. La prima volta la cartella /backup/ultimo non esiste e rsync avvisa, ma esegue comunque una copia completa. Funziona solo se origine e destinazione dei backup stanno sullo stesso file system, che deve supportare gli hard link.
Esempio 11: cosa è cambiato davvero con --itemize-changes
$ rsync -avin progetto/ copia/
.d..t...... ./
>f.st...... index.html
>f+++++++++ nuovo.txtCon -i ogni riga comincia con una sigla di 11 caratteri che spiega perché il file è stato trasferito. In sintesi: >f è un file in arrivo sulla destinazione, +++++++++ indica un file nuovo, s una dimensione diversa, t una data diversa, d una cartella. Utile quando rsync copia file che dovrebbero essere uguali e vuoi capire il perché.
Esempio 12: limitare banda e dimensioni
$ rsync -avz --bwlimit=2000 --max-size=100m progetto/ web:/home/enzo/progetto/
$ rsync -a --stats --human-readable progetto/ copia/
Number of files: 142 (reg: 120, dir: 22)
Number of regular files transferred: 3
Total file size: 48,02M bytes
Total transferred file size: 1,15M bytes--bwlimit limita la velocità (in KiB al secondo; 2000 sono circa 2 MB/s), così il trasferimento non satura la connessione. --max-size salta i file più grandi del limite. Con --stats e -h si ottiene un riepilogo leggibile alla fine.
Esempio 13: uso negli script
#!/bin/bash
ORIGINE="/home/enzo/documenti/"
DESTINAZIONE="web:/home/enzo/backup/documenti/"
LOG="$HOME/backup-rsync.log"
if rsync -az --delete --partial "$ORIGINE" "$DESTINAZIONE" >> "$LOG" 2>&1; then
echo "$(date '+%F %T') backup riuscito" >> "$LOG"
else
CODICE=$?
echo "$(date '+%F %T') ERRORE rsync (codice $CODICE)" >> "$LOG"
exit "$CODICE"
fiIl codice di uscita di rsync è 0 se tutto è andato bene; i valori diversi da zero indicano un problema (per esempio 23 trasferimento parziale per errori su alcuni file, 24 file spariti durante la copia, 12 errore nel flusso dei dati, 255 errore di SSH). In uno script usato dal cron non devono esserci richieste di password: serve l'accesso a chiave (vedi l'articolo su ssh). Lo script va reso eseguibile con chmod +x.
Opzioni utili
-a: modo archivio (ricorsivo, conserva permessi, proprietari, date, collegamenti simbolici); è equivalente a-rlptgoD.-v/-q: più dettagli / silenzioso;-h: dimensioni leggibili;-i: spiega i cambiamenti.-n(--dry-run): simulazione, non cambia nulla.-z: comprime durante il trasferimento (inutile per file già compressi, come immagini, video e archivi).-P: mostra l'avanzamento e conserva i file parziali (--progress --partial).--delete: elimina dalla destinazione ciò che non c'è più nell'origine.--exclude/--include/--exclude-from: scelgono cosa saltare o includere.-e "ssh -p 2222": comando di collegamento (porta o chiave diversa).-u: non sovrascrive i file della destinazione più recenti di quelli dell'origine.-c: confronta il contenuto (checksum) e non data e dimensione: più sicuro ma molto più lento.-H/-A/-X: conserva hard link, ACL e attributi estesi.--backup --backup-dir=DIR: invece di sovrascrivere o cancellare, sposta i vecchi file in una cartella.--link-dest=DIR: backup incrementali con hard link.--bwlimit=KB/s: limita la banda;--max-size/--min-size: filtra per dimensione.--remove-source-files: cancella i file dell'origine dopo averli copiati (in pratica, un "sposta").--rsync-path="sudo rsync": eseguersyncconsudosul server remoto (richiede chesudonon chieda la password).
Attenzione a
- La barra finale sull'origine:
progetto/copia il contenuto,progettocopia la cartella. Sbagliare significa ritrovarsi con una cartella in più (o con file sparsi) nella destinazione. --deleteè pericoloso: se origine e destinazione sono invertite, o l'origine è vuota o non montata, cancella dalla destinazione ciò che c'è. Prima di usarlo, controlla i percorsi con-n. Per una rete di sicurezza si può aggiungere--backup --backup-dir=..., che sposta i file invece di cancellarli.- Origine e destinazione nell'ordine giusto: l'origine viene prima. Il verso della copia non si capisce dal comando se non si legge con attenzione.
- Non è un backup, da solo: una sincronizzazione con
--deletecopia fedelmente anche gli errori. Se cancelli un file per sbaglio e poi sincronizzi, sparisce anche dalla copia. Per un vero backup servono versioni nel tempo (--link-desto--backup-dir) e una copia in un luogo diverso. - Permessi e proprietari:
-aprova a conservarli, ma cambiare proprietario riesce solo arootsulla destinazione. Per copiare file di sistema o di un altro utente servesudo(in locale, o sul server con--rsync-path). - File system senza permessi Unix: copiando su dischi FAT/exFAT o su alcune condivisioni di rete,
-agenera errori su permessi e proprietari. Si usa-rltD(senzap,o,g), tenendo conto che FAT ha una risoluzione delle date di 2 secondi (--modify-window=2). - Gli asterischi e la shell:
rsync -av progetto/* copia/fa espandere l'asterisco alla shell (e salta i file nascosti). Meglio usareprogetto/. Nei percorsi remoti con asterisco servono le virgolette. - Spazi nei nomi: nei percorsi remoti, con versioni vecchie di
rsync, uno spazio nel nome va protetto due volte. Le versioni recenti (3.2.4 e successive) lo gestiscono meglio. Conviene evitare gli spazi nei nomi di file e cartelle. - File aperti e database: copiare con
rsynci file di un database in funzione può produrre una copia incoerente. Meglio un'esportazione (ad esempio conmysqldumpopg_dump) e poi la sincronizzazione del file esportato. - Interruzioni: senza
--partialun file trasferito a metà viene scartato e si ricomincia da capo. Con-Psi riprende. - Collegamenti simbolici: con
-avengono copiati come collegamenti. Se vuoi copiare i file a cui puntano, usa-L. - Se
rsyncè lento: con milioni di file l'elenco iniziale richiede tempo e memoria. Per file già compressi-zaggiunge solo carico di lavoro.
Riepilogo
| Comando | Cosa fa |
|---|---|
rsync -av origine/ destinazione/ | Copia il contenuto di una cartella, conservando i metadati |
rsync -avn origine/ destinazione/ | Simula, senza modificare nulla |
rsync -avz origine/ utente@host:percorso/ | Copia verso un server (con compressione) |
rsync -avz utente@host:percorso/ destinazione/ | Scarica da un server |
rsync -avP file utente@host:percorso/ | Mostra l'avanzamento e permette di riprendere |
rsync -av --delete origine/ destinazione/ | Rende la destinazione identica all'origine |
rsync -av --exclude='*.tmp' origine/ destinazione/ | Esclude file o cartelle |
rsync -a --link-dest=precedente/ origine/ nuovo/ | Backup incrementale con hard link |
rsync -e "ssh -p 2222" ... | Usa una porta SSH diversa |
rsync -avi ... | Spiega il motivo di ogni trasferimento |