Da Aprile 2019 mi sono comprato un server VPS in Germania che uso per gli scopi più disparati. Dal semplice test di funzioni su un sistema Linux (avendo Linux installato solo su macchine virtuali) fino ad esporre servizi su internet.
Come è giusto che sia, ho pensato ad una soluzione di backup, che ho orientato come descriverò di seguito.
Ho attivato un crontab
che, ogni giorno alle 01:00, esegue uno script locato nella mia cartella home.
0 1 * * * /home/user/scripts/backuplibrary.sh
Un sistema di backup semplice quanto efficiente è quello di usare lo strumento tar
con un moderato livello di compressione, impostando un timestamp per differenziare le varie istantanee.
Però c’è un problema: io non aggiorno costantemente la mia libreria. Possono passare settimane prima che possa caricare qualcosa di nuovo o modificare i sample caricati, quindi come fare a controllare se sia già presente una copia di backup e non ne serva un’altra?
Dopo un po’ di test, sono arrivato a questa conclusione:
latest="$(ls -t /home/user/backup/ | head -1)"
filename="backup_$(date +%d-%m-%y_%H:%M).tar.bz2"
tar -cjvf "/home/user/backup/$filename" "/var/lib/docker/volumes/library/_data/" > /dev/null
cmp --silent "/home/user/backup/$latest" "/home/user/backup/$filename" && rm "/home/user/backup/$filename"
Il codice è composto da due sezioni.
La prima sezione è la dichiarazione di due variabili:
La prima viene caricata con il nome del file dell’ultimo backup eseguito.
Il comando ls -t
mostra tutti i file presenti nella cartella, ordinati per ultima creazione. La lista dei file viene passata al comando head -1
, che prende solo la prima riga dell’output ricevuto.
La seconda variabile contiene il nome dell’archivio che andrà a crearsi, composto dal prefisso statico “backup_“, il timestamp corrente fatto da giorno-mese-anno_ora:minuti e l’estensione “.tar.bz2“, in quanto sarà compresso.
Il primo comando della seconda sezione è il semplice comando tar
con i seguenti parametri:
tar -cjvf [nome archivio.tar.bz2] [directory]/
c ─────> Crea archivio
j ────> Comprimi con algoritmo bzip2
v ───> Lista tutti i file inclusi nell'archivio
f ──> Specifica la creazione di un file
Per ultimo, il comando cmp
effettua un confronto tra l’archivio appena creato (il cui nome è contenuto nella variabile $filename
), e l’ultima copia di backup fatta (il cui nome è contenuto nella variabile $latest
).
Invece che giocare con le if
, ho pensato sarebbe stato più efficiente lavorare su una sola riga, perciò ho sfruttato una funzione nativa di BASH: le doppie &&
.
Questa scorciatoia significa “esegui il comando che viene solo se il precedente ha avuto esito positivo” (in termini tecnici, se l’EXIT_CODE è 0).
Quindi si può leggere l’ultima riga con lo pseudocodice:
Confronta i due archivi e, se sono uguali, cancella quello nuovo
Il risultato della cartella di backup è il seguente:
$ ll -th backup/
-rw-r--r-- 1 root root 430M ago 27 01:04 backup_27-08-19_01:00.tar.bz2
-rw-r--r-- 1 root root 429M ago 10 01:02 backup_10-08-19_01:00.tar.bz2
-rw-r--r-- 1 root root 426M ago 8 01:03 backup_08-08-19_01:00.tar.bz2
-rw-r--r-- 1 root root 426M lug 31 01:02 backup_31-07-19_01:00.tar.bz2
-rw-r--r-- 1 root root 424M lug 23 01:02 backup_23-07-19_01:00.tar.bz2
-rw-r--r-- 1 root root 423M lug 18 01:02 backup_18-07-19_01:00.tar.bz2
-rw-r--r-- 1 root root 422M lug 13 01:03 backup_13-07-19_01:00.tar.bz2
-rw-r--r-- 1 root root 421M lug 12 01:03 backup_12-07-19_01:00.tar.bz2
-rw-r--r-- 1 root root 396M lug 6 01:02 backup_06-07-19_01:00.tar.bz2
-rw-r--r-- 1 root root 370M lug 4 01:02 backup_04-07-19_01:00.tar.bz2
-rw-r--r-- 1 root root 366M lug 3 01:02 backup_03-07-19_01:00.tar.bz2
Da come si può vedere, gli archivi non sono stati salvati ogni giorno, ma ogni volta che il contenuto è stato modificato.