Questa guida al backup con rsync e crontab è stata pubblicata per la prima volta nell’agosto del 2005 e aggiornato a novembre 2026: i commenti più vecchi si riferiscono alla versione originale.
Nell’agosto del 2005 avevo un server Debian, una cartella /home che non volevo perdere e una certa tendenza alla paranoia: così ho messo insieme un backup con rsync lanciato da crontab, e ho scritto questo appunto per ricordarmi come. In vent’anni i lettori lo hanno usato, corretto (un refuso nelle righe di cron, segnalato due volte nei commenti) e riempito di domande: come copiare su un altro server, come tenere solo le ultime copie, cosa succede se il computer è spento all’ora del backup.
Questa versione tiene il metodo di allora e lo mette in pari: ho provato ogni comando su Debian 13 con rsync 3.5.0, ho corretto quello che nel 2005 avevo scritto male e ho risposto alle domande dei commenti. In fondo trovi anche un esempio completo per un sito WordPress, database compreso, per chi gestisce il sito su un proprio server.
Cos’è rsync, in breve
rsync copia file e cartelle trasferendo solo le differenze, in locale o tra due macchine: per questo è perfetto per un backup che si ripete ogni giorno.
Nel 2005 partivo dalla definizione degli Appunti di informatica libera di Daniele Giacomini, che resta la più chiara che conosco:
Rsync è un sistema di copia tra elaboratori (o anche all’interno del file system dello stesso sistema locale), in grado di individuare e trasferire il minimo indispensabile di dati, allo scopo di allineare la destinazione con l’origine.
Conta proprio quel minimo indispensabile: la prima copia trasferisce tutto, le successive solo i file cambiati, confrontando di default dimensione e data di modifica. Per questo un backup con rsync che gira ogni notte dura pochi secondi quando non è cambiato quasi nulla. rsync è nei repository di tutte le distribuzioni Linux e su macOS; su Debian e Ubuntu basta sudo apt install rsync. Tutte le opzioni sono nel manuale di rsync.
Il primo backup con rsync
Il comando di base è rsync -a –delete origine/ destinazione/: -a conserva tutto, –delete allinea, e la barra finale decide cosa viene copiato.
Per copiare /home in /backup_giornaliero nel 2005 scrivevo così:
rsync -a -v --delete /home /backup_giornalieroNella versione originale spiegavo -a come «duplica anche le sottodirectory in modo ricorsivo», ed era riduttivo. -a è la modalità archivio: equivale a -rlptgoD, cioè copia ricorsiva, link simbolici, permessi, date di modifica, gruppo, proprietario e file speciali. È quello che serve in un backup, perché un file ripristinato deve tornare identico. Il resto:
| Opzione | Cosa fa |
|---|---|
-a | modalità archivio, equivale a -rlptgoD |
-v | elenca i file copiati (utile a mano, rumoroso in cron) |
--delete | cancella dalla destinazione i file che non esistono più nell’origine |
-n o --dry-run | simula: mostra cosa farebbe senza toccare nulla |
--mkpath | crea le cartelle mancanti del percorso di destinazione |
Due avvertenze che nel 2005 mancavano. La prima: prima di usare –delete, prova con –dry-run. Con origine e destinazione invertite, --delete ti allinea l’originale alla copia vecchia, e non c’è un cestino. La seconda è la barra finale della sorgente, che un lettore ha capito «a sue spese»: /home copia la cartella e crea /backup_giornaliero/home, mentre /home/ copia solo il contenuto. Sulla destinazione invece la barra è indifferente.

La barra finale cambia la destinazione
| Comando | Risultato |
|---|---|
rsync -a /home /backup | copia la cartella: /backup/home/ |
rsync -a /home/ /backup | copia il contenuto: /backup/maurizio/ |
Nell’originale chiudevo con «ricordiamoci di creare le directory!!!». Nella prova su Debian 13 rsync crea da solo l’ultima cartella del percorso, ma si ferma con un errore se manca anche quella sopra; con –mkpath crea tutto il percorso. Da qui in avanti uso la forma con la barra: rsync -a --delete /home/ /backup_giornaliero/.
Automatizzare con crontab
cron esegue i comandi agli orari scritti in una tabella: cinque campi per minuto, ora, giorno, mese e giorno della settimana, poi il comando.
Per automatizzare il backup con rsync nel 2005 ho aggiunto una riga a /etc/crontab. I file di sistema (/etc/crontab e quelli in /etc/cron.d/) hanno un sesto campo con l’utente che esegue il comando; la crontab personale, che si modifica con crontab -e, non ce l’ha. Oggi preferisco un file dedicato in /etc/cron.d/, così il backup non si mescola con il resto del sistema.
| Campo | Valori | Nell’esempio |
|---|---|---|
| minuto | 0-59 | 0 |
| ora | 0-23 | 23 |
| giorno del mese | 1-31 | * (tutti) |
| mese | 1-12 | * |
| giorno della settimana | 0-7 (0 e 7 sono domenica) | * |
# /etc/cron.d/backup
0 23 * * * root rsync -a --delete /home/ /backup_giornaliero/Ogni sera alle 23 parte rsync. È proprio qui che due lettori, nel 2008 e nel 2009, mi hanno fatto notare uno zero di troppo all’inizio delle righe: un campo in più e cron interpreta tutto in modo diverso. Con crontab -e l’errore si vede subito, perché un’ora come 25 viene rifiutata con «bad hour»; i file di /etc/cron.d/ invece non hanno questo controllo, quindi rileggili due volte. La sintassi completa è nella pagina di manuale di crontab.
Tre copie, perché sono paranoico
Un backup con rsync e –delete è uno specchio: se cancelli un file per sbaglio, la sera stessa sparisce anche dal backup. Per questo ne tengo tre.
Nel 2005 la motivazione era semplice: «dato che sono paranoico e che un backup non mi basta». Rileggendola, la paranoia aveva una ragione tecnica che allora non avevo scritto: con --delete ogni copia insegue l’originale, errori compresi. Tre copie con ritmi diversi danno il tempo di accorgersene.
# /etc/cron.d/backup
0 23 * * * root rsync -a --delete /home/ /backup_giornaliero/
0 2 * * 0 root rsync -a --delete /home/ /backup_settimanale/
0 5 1 * * root rsync -a --delete /home/ /backup_mensile/La giornaliera parte ogni sera alle 23, la settimanale la domenica alle 2, la mensile il primo del mese alle 5. Un file cancellato per sbaglio il lunedì sparisce dalla giornaliera la sera stessa, ma resta nella settimanale fino alla domenica e nella mensile fino al primo del mese successivo.

Tre copie a rotazione con cron
| Copia | Quando | Riga di cron |
|---|---|---|
| Giornaliera | ogni sera alle 23 | 0 23 * * * |
| Settimanale | domenica alle 2 | 0 2 * * 0 |
| Mensile | il primo del mese alle 5 | 0 5 1 * * |
Sapere se il backup è andato
cron manda per email tutto quello che un comando scrive: con MAILTO e senza -v ricevi un messaggio solo quando qualcosa va storto.
Nel 2005 la domanda finale era: come faccio a sapere se il backup con rsync è stato eseguito? La risposta era una pipe verso mail, che però ti manda un messaggio ogni sera, anche quando va tutto bene. Dopo qualche settimana non lo legge più nessuno. Meglio sfruttare il comportamento di cron: quello che un comando scrive viene spedito all’indirizzo della variabile MAILTO. Senza -v, rsync scrive solo gli errori.
# /etc/cron.d/backup
MAILTO=tuamail@dominio.it
0 23 * * * root rsync -a --delete /home/ /backup_giornaliero/Serve un programma che spedisca la posta dal server, e nei commenti c’era chi l’aveva risolto con postfix e mailx. Se il server non può inviare email, l’alternativa è scrivere l’esito in un file di log e controllarlo con lo strumento di monitoraggio che usi già.
Snapshot con –link-dest
Con –link-dest ogni backup è una cartella completa con la sua data, ma i file non cambiati non occupano spazio: sono hard link alla copia precedente.
Nel 2019 un lettore mi chiedeva come tenere le ultime tre copie mensili, cancellando la più vecchia a ogni giro. La risposta di oggi è un backup con rsync a snapshot: una cartella per giorno, ognuna completa, con l’opzione –link-dest che collega i file identici a quelli della copia precedente invece di duplicarli.
#!/bin/sh
# /usr/local/bin/backup-snapshot.sh
set -eu
DEST=/backup/snapshot
OGGI=$(date +%F)
mkdir -p "$DEST"
rsync -a --delete --link-dest="$DEST/ultimo" /home/ "$DEST/$OGGI/"
ln -sfn "$DEST/$OGGI" "$DEST/ultimo"
# tiene le ultime 30 copie e cancella le più vecchie
ls -1d "$DEST"/20* | head -n -30 | xargs -r rm -rfNella prova, un file non modificato tra due snapshot aveva lo stesso inode in entrambe le cartelle: un solo file su disco, visibile in due posti. Al primo giro rsync avvisa che ultimo non esiste e fa una copia completa, poi tutto procede da solo. Per ripristinare basta copiare indietro dalla cartella del giorno che ti serve, con un normale cp o con rsync. La riga in cron usa flock, che impedisce di far partire un secondo backup mentre il primo è ancora in corso:
30 3 * * * root flock -n /tmp/backup.lock /usr/local/bin/backup-snapshot.shIl backup su un altro server
Un backup con rsync sullo stesso disco non sopravvive al disco: rsync copia via SSH su un’altra macchina con la stessa sintassi, cambiando solo la destinazione.
Nel 2010 un lettore mi chiedeva come trasferire il backup su un altro server, «per essere sicuri». Allora suggerivo di montare la cartella remota; oggi rsync lo fa da solo via SSH, aggiungendo utente e host alla destinazione:
rsync -a --delete /home/ copie@server-backup:/srv/backup/home/Perché funzioni da cron serve una chiave SSH senza passphrase dedicata al backup, autorizzata sul server di destinazione per un utente che può scrivere solo nella cartella delle copie. Un dettaglio trovato durante la prova: su Debian esiste già un utente di sistema chiamato backup, senza shell, quindi per l’utente remoto conviene un altro nome. Sulla sicurezza del server SSH ho due vecchi appunti, le tre righe per la sicurezza di SSH e il controllo degli accessi.
Esempio: backup di un sito WordPress
Un sito WordPress è fatto di file e database: si esporta il database con WP-CLI, poi rsync porta file e dump su un altro server.
Se il tuo sito WordPress gira su un server o un VPS che gestisci tu, copiare solo i file non basta: articoli, pagine, utenti e impostazioni stanno nel database. Nel 2007 lo risolvevo con un backup di MySQL via mail; oggi c’è WP-CLI, che legge le credenziali da wp-config.php e con wp db export produce un file .sql. Lo script completo del backup con rsync:
#!/bin/sh
# /usr/local/bin/backup-wordpress.sh
set -eu
SITO=/var/www/miosito # dove sta WordPress
DUMP=/home/miosito/backup/database.sql # fuori dalla cartella pubblica
REMOTO=copie@server-backup:/srv/backup/miosito
# 1. il database in un file .sql (WP-CLI legge le credenziali da wp-config.php)
wp --path="$SITO" db export "$DUMP" --quiet
# 2. i file del sito, senza la cache, e il dump del database
rsync -a --delete --exclude='wp-content/cache/' "$SITO/" "$REMOTO/sito/"
rsync -a "$DUMP" "$REMOTO/"E la riga di cron, eseguita con l’utente proprietario del sito (WP-CLI sconsiglia di girare come root):
# /etc/cron.d/backup-wordpress
MAILTO=tuamail@dominio.it
30 3 * * * miosito flock -n /tmp/backup-wp.lock /usr/local/bin/backup-wordpress.sh
Backup di un sito WordPress con rsync
| Passo | Come |
|---|---|
| 1. cron | 30 3 * * *, flock evita i doppioni |
| 2. database | wp db export, file .sql fuori dal sito |
| 3. file | rsync -a --delete, senza wp-content/cache |
| 4. altro server | via SSH con chiave, copie@server-backup |
L’ho provato in un container Debian 13 con un WordPress appena installato: il dump è arrivato sul server di destinazione insieme ai file, e la cartella della cache è rimasta fuori. Tre cose da non saltare: il dump va fuori dalla cartella pubblica del sito, altrimenti chiunque potrebbe scaricarlo; per avere più giorni a disposizione si combina lo script con gli snapshot visti sopra; e un backup vale qualcosa solo se hai provato almeno una volta a ripristinarlo.
Su un hosting condiviso, invece, di solito ci pensa il provider: nella mia manutenzione WordPress non teniamo copie nostre e per un ripristino partiamo dal backup del servizio di hosting, per non duplicare dati che riguardano te e i tuoi clienti. Per lo stesso motivo anche Fleet, il cruscotto che ho costruito per la manutenzione dei siti, non fa backup. In entrambi i casi la prima cosa da fare è verificare che i backup automatici del piano di hosting siano attivi; lo script qui sopra serve quando il server è tuo o quando vuoi una copia in più su un’altra macchina.
Paranoico nel 2005, paranoico oggi
rsync e crontab fanno ancora benissimo il loro lavoro: basta sapere cosa fa –delete, tenere più copie e metterne almeno una su un’altra macchina.
Rileggere un articolo del 2005 è un po’ come aprire un cassetto: il metodo regge, qualche dettaglio no. Il backup con rsync e crontab resta il modo più semplice per avere una copia aggiornata di una cartella o di un sito, senza installare nient’altro. Quello che rsync non fa da solo è cifrare le copie o tenerne molte versioni in poco spazio su un servizio esterno: lì entrano in gioco strumenti come restic o Borg, ma è un altro articolo.
- prova sempre con
--dry-runprima di usare--delete; - metti la barra finale sulla sorgente e chiediti cosa vuoi trovare nella destinazione;
- tieni almeno due copie con ritmi diversi, oppure gli snapshot con
--link-dest; - porta una copia su un’altra macchina e fai una prova di ripristino.
Se il server rallenta mentre gira il backup, tornano utili i sette modi per esaminare il carico; se preferisci un pannello al terminale, c’è sempre Webmin, che ha anche un modulo per cron. E se vuoi capire se il tuo sito WordPress è davvero coperto, puoi prenotare una call.
Nei commenti raccontami come fai i tuoi backup e da quanti anni ti salvano: se conosci qualcuno che ha ancora una sola copia, sullo stesso disco, girargli questo articolo è un gesto d’amore.
Domande frequenti su rsync e crontab
Come si fa un backup con rsync e crontab?
Si scrive il comando rsync, per esempio rsync -a --delete /home/ /backup/, e lo si aggiunge a una crontab con l’orario: 0 23 * * * lo fa partire ogni sera alle 23. Nei file di sistema come /etc/cron.d/ va indicato anche l’utente, di solito root.
Cosa fa l’opzione –delete di rsync?
Cancella dalla destinazione i file che non esistono più nell’origine, così la copia resta identica. È utile ma pericolosa: un file cancellato per sbaglio sparisce anche dal backup alla copia successiva. Prima di usarla conviene provare con --dry-run.
Che differenza c’è tra /home e /home/ in rsync?
Senza barra finale rsync copia la cartella stessa, quindi nella destinazione trovi home/; con la barra copia solo il contenuto. La barra conta solo sulla sorgente.
Come faccio il backup con rsync su un altro server?
Si indica la destinazione come utente@server:/percorso/: rsync usa SSH. Per farlo girare da cron serve una chiave SSH dedicata, autorizzata sul server di destinazione.
Se il computer è spento all’ora del backup, cron lo recupera?
No: cron salta le esecuzioni perse. Su un computer che non resta sempre acceso si può usare anacron, che recupera i lavori giornalieri, settimanali e mensili al primo avvio utile.
Perché rsync dice «file too large»?
Di solito la destinazione è un disco FAT32, che non accetta file più grandi di 4 GB. Per i backup conviene un file system come ext4.





Semplice e preciso. Ottimo articolo, complimenti.
Hai aggiunto uno zero di troppo all’inizio di tutte le linee in crontab. I comandi corretti sono del tipo:
0 23 * * * root rsync -a -v –delete /home /backup_giornaliero
I campi in crontab sono solo 5 (vedi http://it.wikipedia.org/wiki/Crontab)
@marco,
grazie!!!
non mi ero mai accorto del refuso… 😉
che programma hai installato per poter fare in modo che il comando mail funzioni? php, postfix? grazie, ottima guida!
http://packages.debian.org/stable/mail/mailx
per installarlo sotto debian… apt-get install mailx
😉
si sono sotto ubuntu (server 7.10) ma bisogna configurarlo in qualche maniera (cioè di fatto creare un server mail) o funziona già da solo(vedo che usa postfix)?
penso che un server smtp sia già installato di default.
il modo più veloce per saperlo è provare…
echo “prova” | mail tuamail@dominio.ext -s “prova invio”
se dovesse dare un qualche tipo di errore allora possiamo valutare se procedere con l’installazione di un MTA come postfix
apt-get install postfix
per riconfigurarlo: dpkg-reconfigure postfix
ho risolto:
1) apt-get install postfix
2) dpkg-reconfigure postfix
3) apt-get install mailx
e tutto funzia…
Grazie mille
> Ho editando il file /etc/crontab e aggiunto questa riga:
> 0 0 23 * * * root rsync -a -v –delete /home /backup_giornaliero
occhio che c’e’ ancora un campo in piu’, ad inizio riga 🙂
@ maaaatteo,
grazie corretto 😉
ciao, complimenti per il blog lo sto seguendo con interesse.
e’ possibile salvare il backup su un account ftp che voi sappiate?
@andrea,
ti lascio un link che dovrebbe rispondere alla tua domanda:
How to use ftp in a shell script.
In questo modo puoi far partire la copia ftp subito dopo aver terminato la sincronizzazione.
Ciao, innanzitutto complimenti per il blog… poi non ho capito bene a cosa serve l’opzione –delete? e anche se rsync mi permette di fare un backup direttamente in rete del tipo :
rsync -a -v –delete 192.168.1.10/Home /backup_giornaliero
Grazie e Ciao
una domanda: e se quando crontab ha stabilito il momento del backup il pc è spento? lo esegue al primo avvio successivo?
e metti che al primo riavvio abbia necessità di spegnere il pc quasi subito…che faccio, lascio rsync a metà?
grazie per le risposte ai dubbi
@BUcky,
sì secondo me puoi mettere uno script in avvio del pc.
se poi lo spegni e lo lasci a meta al limite la volta successiva ricomincia da dove è rimasto….
innanzitutto coomplimentoni x il blog! Dopo questa sviolinata volevo chiederti una cosa. Mailx può inviare email anche fuori dalla propria lan? Se è così hai qualche link di guide in italiano?
Grazie
se nella tuo distro è installato un server smtp come postfix puoi mandare la mail dove vuoi.
questa è la sintassi:
#echo “testo del messaggio” | mail nome@mail.com -s “soggetto”
negli esempi sopra mi mandavo lo stdout di rsync come corpo della mail.
Non mi completa il backup cone errore
rsync: file too large (27) errors.
cosa può essere?
potrebbe essere che stai facendo il backup su un disco formattato fat32 che non supporta file più grossi di 2gb?
non mi viene in mente molto altro….
cerca di capire se usando un’altro disco di destinazione di presentano gli stessi problemi…
Si in ext3 funziona, in fat32 non va oltre i 4GB
QUal’è la sintassi di un computer A che vuole fare il backup della /etc locale, su un HD di server remoto /media/hdesterno?
Il tuo lavoro mi ha risparmiato un sacco di tempo e fatica.
Grazie!
Grazie…articolo ben fatto!Ho fatto in poco tempo quello che temevo mi prendesse molto molto + tempo.
Complimenti per l’articolo semplice ed efficace. Approfitto della tua sapienza. ma se volessi trasferire il backup in un altro server diverso da quello locale per essere sicuri?
io in passato avevo usato ssh per montare una directory remota e poi con rsync avevo fatto la sinccronizzazione…
se non di sono dati “riservati” oggi provereri anche a fare qualche esperimento con le api di dropbox
diciamo che molto dipende dal tipo di macchina locale e remota…
in remoto parliamo di SAN o di server?
la macchina locale cosè ? è sempre accesa ?
come sono collegate ? c’è un vpn ?
vabbè… ho già fatto troppe domande… 😀
anche a me questo post ha fatto risparmiare tempo e fatica, grazie infinite.
Mi troverei, però, di fronte ad una seccatura da mettere a posto: il backup è davvero corposo (quasi 200 GB) ed il report è troppo lungo, impedendomi di vedere se e dove ci sono cambiamenti.
Come posso filtrare, facendo in maniera che non appaiano nel report, tutte le righe “nomefile is uptodate”, al limite contandole?
Grazie ancora
puoi filtrarlo con grep aggiungendo l’opzione -v (invert mach)
es:
rsync -a -v –delete /home /backup | grep -v “is uptodate” | mail tuamail -s “Log”
in questo modo ti vengono mandate via mail solo le righe dove non è presente “is uptodate”.
fammi sapere se funziona…
è perfetto!!! grazie infinite!!!
come posso rigraziare?
@stef@no,
..bene sono contento 😉
per ringraziarmi puoi aggiungere questo sito ai tuoi preferiti e fami un po’ di pubblicità, oppure se proprio non riesci a farne a meno c’è l’opzione caffè
fatte entrambe le cose.
Grazie ancora a te!!! 🙂
non ricordavo bene la sintassi di crontab 🙂
anch’io sono un “maniaco” dei backup e la sicurezza dei dati non è mai troppa 😉
grazie
Pol
[…] backup file e database (WordPress Backup / WordPress database […]
utilizzo con molta soddisfazione rsync e crontab.
ho capito a mie spese (con delete) il significato dello slash della directory origine.
non ho capito la differenza dello slash nella direcytory di destinazione.
grazie
mario del pia
Una domanda…o forse due…
Una volta inserito il comando di backup nel file crontab quando viene il momento di effettuare il backup il boot rimane bloccato finché non finisce ? In tal caso, quanto dura tale processo ?
Perché invece di farci mandare una mail non reindirizziamo l’output in un file di log ?
La domanda più scontata: Come si fa a sostituire i file del sistema con quelli di backup in caso di problemi ? Sono salvati in archivi speciali o semplicemente hanno l’estensione .back o simili ?
Salve sono ancora poco pratico di programmazione ma vorrei il backup mensile salvare le ultime 3 copie, a rotazione ogni volta che si aggiunge una nuova l’ultima più vecchia si cancelli automaticamente come potrebbe essere la stringa?
Con rsync e crontab, il backup diventa un’arte: automatizza il processo di salvataggio dei tuoi dati, garantendo sicurezza e tranquillità senza dover alzare un dito.