creare un backup incrementale di un volume di rete con snow leopard ed il terminale unixL'articolo di oggi è un po' tecnico, ma risponde ad una domanda che mi è stata fatta diverse volte, ovvero: come si fa un backup incrementale con Snow Leopard? Prima di tutto vediamo il significato del termine. Un backup incrementale crea una copia dei nostri file su un disco di rete (o locale), aggiungendo di volta in volta tutti i nuovi file e  sovrascrivendo quelli più recenti. In questo modo ci si assicura di non perdere nessun file, anche quelli che poi vengono cancellati dagli Hard Disk oggetto del backup.

Solitamente questo tipo di backup ha senso quando è automatico ed eseguito in background in momenti prestabiliti, in modo da non doverci preoccupare di attivare la procedura manualmente.

La buona notizia è che su Mac OS X, grazie al granitico cuore Unix, la procedura è realizzabile senza l'ausilio di software aggiuntivi. Quella cattiva è che bisogna sporcarsi un po' con il terminale. Ma di sicuro non ci farà male!

Al termine di questo articolo, creeremo un'operazione programmata (con crontab) di uno script che esegue la connessione (mount) di un volume di rete condiviso (mediante samba), esegue il backup incrementale e crea un diario (log) del risultato. Considerando che può essere piuttosto complesso, proseguiremo per gradi.

Bene, il comando da eseguire per il backup è rsync. E una sua possibile implementazione è la seguente:

/usr/bin/rsync --recursive --times --specials SORGENTE DESTINAZIONE

Se volete conoscere il significato delle opzioni che ho indicato prima delle cartelle  SORGENTE e DESTINAZIONE, potete approfondire sulla pagina del manuale di rsync. Per ottenere i percorsi reali delle cartelle in gioco, trascinatele nell'area del terminale.

A questo punto siamo già in grado di creare uno script che esegue tale backup. Assicuratevi che sia la sorgente che la destinazione siano raggiungibili e poi aprite il vostro programma preferito per la scrittura di codice. In questo caso è ottimo TextWrangler (o Smultron). Iniziate le prima riga con il seguente commento:

#!/bin/sh

e poi incollate il codice di sopra, sostituendo i vostri percorsi a SORGENTE e DESTINAZIONE. Create una cartella Script nella vostra home (quella con il vostro nome) e salvateci dentro il file in questione, con il nome "backup.incrementale.sh". A questo punto se volete iniziare a provarlo, potete eseguirlo aprendo il Terminale e digitando:

/bin/sh ~/Script/backup.incrementale.sh

Il caso che voglio esaminare oggi però è più complesso, in quanto esegue il backup su un volume di rete. Per utilizzare questo volume in locale è necessario montarlo e per farlo si usa il comando mount. Un percorso di rete si raggiunge con un indirizzo IP (o un nome) e vi si accede conoscendo nome utente e password, se è protetto. Una possibile implementazione di mount è la seguente:

/sbin/mount -t smbfs //GUEST:@192.168.1.2/backup /Volumes/tmpbackup

Con questa riga si monta sul percorso locale /Volumes/tmpbackup la cartella /backup raggiungibile tramite l'IP 192.168.1.2, il quale non è protetto da password e pertanto vi si accede come GUEST (ospite). La cartella di destinazione /Volumes/tmpbackup deve però già essere creata. In caso fosse necessario autenticarsi, la password va inserita tra i due punti e la chiocciola. Il comando può essere eseguito da Terminale e, se va a buon fine, apparirà un nuovo volume di rete sul Mac, con relativa icona sulla scrivania. A questo punto il disco remoto può essere usato come uno locale, quindi potremmo sostituire a DESTINAZIONE il nostro /Volumes/tmpbackup.

Notate che il volume è montato come file system smbfs. Per maggiori dettagli sui tipi disponibili verificare il manuale di mount. Terminato il backup possiamo smontare il volume. Useremo prima di ogni riga il comando ECHO che stampa a video una stringa. In questo modo avremo la duplice funzione di capire leggendo il codice cosa faccia la riga successiva e di avere un output a video della progressione dello script. Quindi il nostro script diventerà:

#!/bin/sh
echo "MI ASSICURO CHE ESISTA LA CARTELLA /Volumes/tmpbackup";
mkdir /Volumes/tmpbackup 2>/dev/null
echo "MONTO VOLUME DI RETE";
/sbin/mount -t smbfs //GUEST:@192.168.1.2/backup /Volumes/tmpbackup
echo "ESEGUO BACKUP INCREMENTALE"
/usr/bin/rsync --recursive --times --specials SORGENTE /Volumes/tmpbackup
echo "SMONTO VOLUME DI RETE"
/sbin/umount /Volumes/tmpbackup
echo "CANCELLO LA CARTELLA /Volumes/tmpbackup";
rmdir /Volumes/tmpbackup

Se però il comando mount non dovesse andare a buon fine per qualsivoglia motivo, la cartella /Volumes/tmpbackup rimarrebbe come una cartella locale e quindi rischieremmo di fare un backup sul nostro stesso Mac. Spiego meglio: noi creiamo una cartella locale dentro /Volumes a cui associamo con mount un percorso di rete. Se quest'ultima operazione non dovesse funzionare, la cartella non sarebbe associata al volume di rete e la copia verrebbe dunque effettuata localmente.

Una possibile soluzione è quella di creare una cartella nel volume di rete e poi verificare la sua presenza con lo script. Se la troviamo il mont è andato a buon fine. Con la scusa creiamo una cartella che ci tornerà utile per tenere traccia dei backup e la chiameremo "_log" (l'underscore lo inseriamo così che questa venga sempre posizionata in cima alla lista).

Dopo aver creato la cartella nel volume di rete, aggiorniamo lo script, inserendo la verifica e facendo creare a rsync un diario dei backup:

#!/bin/sh
echo "MI ASSICURO CHE ESISTA LA CARTELLA /Volumes/tmpbackup";
mkdir /Volumes/tmpbackup 2>/dev/null
echo "MONTO VOLUME DI RETE";
/sbin/mount -t smbfs //GUEST:@192.168.1.2/backup /Volumes/tmpbackup

echo "VERIFICO mount TRAMITE PRESENZA DELLA CARTELLA /Volumes/tmpbackup/_log"
if [ ! -d /Volumes/tmpbackup/_log ];
then
	echo "MOUNT ERRATO, BACKUP ANNULLATO";
else
	echo "ESEGUO BACKUP INCREMENTALE"
	/usr/bin/rsync --recursive --times --specials SORGENTE /Volumes/tmpbackup --log-file=/Volumes/tmpbackup/_log/backup_$(date +\%Y\%m\%d).txt
	echo "SMONTO VOLUME DI RETE"
	/sbin/umount /Volumes/tmpbackup
fi

echo "CANCELLO LA CARTELLA /Volumes/tmpbackup";
rmdir /Volumes/tmpbackup

La sintassi IF/THEN/ELSE/FI va letta come SE/ALLORA/ALTRIMENTI/FINE SE. In pratica diciamo che se dopo il mount non riusciamo a raggiungere la cartella /Volumes/tmpbackup/_log allora non eseguiamo il backup, perché evidentemente il mount non è andato a buon fine. Ovviamente il codice così com'è è ancora largamente perfettibile, perché ho cercato di ridurre all'osso i concetti per renderli comprensibili.

L'ultimo passaggio è quello di rendere il backup automatico. Aprite il terminale e scrivete

sudo crontab -e

vi verrà richiesta la password amministrativa e poi vi troverete in un'area editabile. Premete un carattere per iniziare ad editare (apparirà -- INSERT -- in basso). Incollate qui il seguente codice, o riproducetelo manualmente se preferite (gli spazi orizzontali sono creati con il tasto TAB):

#m      h       mday    month   wday    command
0       13,22   *       *       *       /bin/sh ~/Script/backup.incrementale.sh

Così come è scritto il comando che esegue lo script di backup, verrà eseguito dal nostro computer tutti i giorni della settimana, alle ore 13:00 e alle ore 22:00. Per modificare i parametri al fine di scegliere l'intervallo che preferite, fate riferimento alla pagina del manuale di crontab.

Quando avete definito il tutto, premete ESC (dovrebbe sparire la scritta -- INSERT --) e digitate :wq e poi premete invio. Il comando esegue un salvataggio (write) ed esce (quit).

Spero che sia tutto chiaro! In bocca al lupo con i vostri backup incrementali!