Backup in rete pratico e veloce con FTP – 2

Dopo quasi, ahem, un anno di stasi, vediamo di chiudere l’agomento inziato con il primo post Backup in rete pratico e veloce con FTP -1, passando alla parte più “operativa”.

backup_tape.jpg

Vediamo, qui di seguito, un semplice shell script che si occupa di creare un backup all’interno di un file tgz, che avrà come prefisso la data del giorno di archiviazione. Creato il file, provvederà a trasferirlo via ftp sulla macchina d’appoggio, e infine cancellerà l’archivio il cui suffisso sarà costituito dalla data odierna – 15 giorni.

Prima di procedere, però, un avvertimento: questo post è decisamente lungo e, per qualche verso, anche noioso.

Non dite che non vi avevo avvisati 🙂

Rendere uno script portabile e flessibile, l’intestazione

A cosa serve uno script? Beh, semplicemente, banalizzando, a rendere semplici e veloci operazioni ripetitive, a sollevare l’utente da una routine che non richiede una particolare attenzione.

Ciò vale anche per lo script stesso. Ovvero, non deve solo rendere semplici le altre operazioni, ma deve semplificare al tempo stesso la sua gestione. Uno programma, per quanto piccolo, che dia luogo a malfunzionamenti appena lo si tocchi o sposti, oppure che sia difficile da modificare a seconda delle esigenze contingenti, non assolve pienamente agli scopi cui canonicamente è deputato.

Allora, come rendere semplice la gestione di uno script?

In prima battuta, possiamo pensare a due potenziali scenari problematici:

  1. Lo script, che è sempre andato bene, deve essere modificato, magari, nel nostro caso, per includere nuove directory o per escluderne altre, per modificare la denominazione dei file di archivio, oppure per modificare l’arco di ritenzione dei backup sul server FTP remoto su cui appoggeremo i file compressi;

  2. Lo script, che è sempre andato bene, deve essere spostato su una differente distribuzione Linux o su una variante Unix, nella quale le utility di sistema sono poste in posizioni differenti nell’albero delle directory.

Nel primo caso, saremo costretti a scorrere tutto il file alla ricerca di ogni evenienza della porzione da modificare, mentre i più esperti dovranno evocare arcane stringhe composte da sed, awk e cut.

Nel secondo caso, bisognerà scorrere tutto il programma, cercare il riferimento al percorso delle utility impiegate, confrontarlo con il percorso delle stesse nel nuovo sistema e apportare le modifiche del caso.

Operazioni scomode entrambe, non vi pare? Scomode e portano via parecchio tempo, prone come sono agli errori.

Meglio ricorrere a un espediente del tutto lecito e semplice da utilizzare, ovvero creare
un’intestazione allo script, ovvero una parte iniziale completamente parametrizzata, grazie alla quale ogni elemento modificabile sarà racchiuso in una variabile, che verrà poi richiamata al momento opportuno, nella parte elaborativa del programma. Per cambiare quindi un valore, basterà modificare il contenuto della variabile cui è associato e quindi la modifica verrà riflessa in ogni punto dello script in cui la variabile stessa verrà richiamata. Semplice, efficace, pulito.

Il secondo espediente cui ricorreremo è definito comunemente “sostituzione di comando”, ovvero si istanzia una variabile non tanto con un valore predefinito, quanto con il risultato di un comando da eseguire. Vedremo in seguito più dettagliatamente di cosa si tratta, basterà ora un esempio schematico.

Volendo richiamare il comando tar, lo si può indicare per esteso, per esempio


/bin/tar

In questo caso, non ci sono particolari note da rilevare. Lo script richiamerà il programma semplicemente seguendo il percorso indicato.

Piccolo, grande problema: se lo script viene spostato su un sistema in cui l’utility tar si trova in un percorso differente, il programma non eseguirà l’utility indicata, dato che il percorso non porterà a nulla di utilizzabile. Se, però, invece di utilizzare una indicazione statica si chiede a un’utility di sistema di trovare tutte le altre, il punto di fallimento viene ridotto all’unico primo programma richiamato “alla cieca”. Facciamo un esempio


TAR=$(which tar)

In questo caso, abbiamo chiesto all'utility which di trovare il percorso dell’utility tar e abbiamo assegnato il percorso stesso alla variabile TAR. In questo modo, dovremo fare attenzione unicamente al fatto che which sia richiamabile direttamente dall’ambiente legato all’account utilizzato per eseguire lo script (ovvero che il suo percorso sia compreso nella variabile d’ambiente PATH). Accertato ciò, basterò richiamare il contenuto della variabile TAR per eseguire il comando rintracciabile al percorso assegnato.

Torneremo sull’argomento più avanti, non vi preoccupate.

Lo script di backup

Un po’ di attenzione, non è difficile. Prima vediamo lo script al completo, poi esamineremo le varie parti interessanti.


#!/bin/sh

RM=$(which rm)
TAR=$(which tar)
TAR_OPTS="cvzf"
TAR_REMOVE="--remove-files -cvzf"
FTP=$(which ftp)
FIND=$(which find)
ECHO=$(which echo)
DATA=$(which date)
DATE=$($DATA +%F)
RM_DATE=$(date --date='15 days ago' +'%Y-%m-%d')

ARCHIVE="$DATE-nome-del-server.backup.tgz"
ARCHIVE_MYSQL="$DATE-mysql.nome-del-server.com.backup.tgz"
BACKUP_SPOOL="/var/spool/backup"
BACKUP_DIR="/usr/local/apache /usr/local/mysql/ /var/mysql /var/lib/awstats /etc/ $BACKUP_SPOOL/$MYSQL_BACKUP_FILE"
BACKUP_EXCLUDE_DIR="/usr/local/apache/tmp/ /usr/local/apache/htdocs/data/videos/ /var/spool/backup /etc/passwd /etc/shadow"

BACKUP_MACRO="backup"

MYSQL_DUMP=$(which mysqldump)

MYSQL_OPTS="--socket=/usr/local/apache/mysql.sock/mysql.sock --all-databases --user=nome_utente --password=password_di_accesso"
MYSQL_BACKUP_FILE="$DATE-mysql.nome-del-server.com.backup.sql"
SERVER="indirizzo-del-server-di-appoggio"

$MYSQL_DUMP $MYSQL_OPTS > $BACKUP_SPOOL/$MYSQL_BACKUP_FILE

$TAR $TAR_REMOVE $BACKUP_SPOOL/$ARCHIVE_MYSQL $BACKUP_SPOOL/$MYSQL_BACKUP_FILE

$FIND $BACKUP_EXCLUDE_DIR > $BACKUP_SPOOL/IGNORE.LST

$TAR $TAR_OPTS $BACKUP_SPOOL/$ARCHIVE -X $BACKUP_SPOOL/IGNORE.LST $BACKUP_DIR

$ECHO "\$ $BACKUP_MACRO $RM_DATE" | $FTP $SERVER

$RM $BACKUP_SPOOL/$ARCHIVE $BACKUP_SPOOL/$ARCHIVE_MYSQL

Complicato? No, sembra esserlo ma è più semplice di quanto non si immagini.

Diamo un'occhiata più da vicino ad alcune delle prime righe, esclusa la sha-bang, ovvero a quelle che ci consentiranno di creare i nomi dei file di backup, in modo che racchiudano la data in cui gli archivi sono stati creati:


DATA=$(which date)
DATE=$($DATA +%F)
RM_DATE=$(date --date='15 days ago' +'%Y-%m-%d')
ARCHIVE="$DATE-nome-del-server.backup.tgz"
ARCHIVE_MYSQL="$DATE-mysql.nome-del-server.com.backup.tgz"

Come primo accorgimento, eseguiamo una sostituzione di comando. In pratica, la variabile DATA viene istanziata con l’output del comando which date.

Cosa significa tutto ciò? Facciamo ricorso alla shell e vediamo cosa succede. Iniziamo con l’eseguire il comando which date:


zarrelli@moveaway:~$ which date
/bin/date
zarrelli@moveaway:~$

Semplicemente, which restituisce il percorso al comando che gli si fornisce come argomento, sempre che il comando sia all'interno di una delle directory indicate nella variabile d'ambiente PATH correlata all’utente che ha lanciato il comando which.

Controprova:


zarrelli@moveaway:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
zarrelli@moveaway:~$

oppure:


zarrelli@moveaway:~$ env | grep PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
zarrelli@moveaway:~$

Perché utilizzare una sostituzione di comando? Perché in questo modo avremo degli script portabili. Ovvero, posto che si utilizzino delle utility di sistema, anche se queste, a seconda delle distribuzioni utilizzate, o delle varianti Unix adottate, si trovano in un percorsi differenti da quelli in cui risiedono all’interno del sistema utilizzato per creare lo script, la sostituzione di variabile rende sempre possibile invocarle, senza preoccuparsi di dove siano localizzate nel file system.

Fatto salvo che, ovviamente, l’utility puntata dalla sostituzione di variabile sia in un percorso compreso all’interno della variabile PATH, ma ciò è verificato nel momento in cui si utilizzino utility di sistema e ambienti variabili di sistema predefinite.

Quindi, la variabile DATA conterrà il percorso all’utility date, ovunque essa si trovi, all’interno delle directory comprese nella variabile PATH.

Ora che abbiamo la possibilità di richiamare facilmente il comando date, istanziamo una variabile DATE con il valore restituito ($) dall’utility di sistema date, la quale a sua volta mostrerà la data di sistema, formattandone l’output nel formato numerico anno-mese-giorno, grazie all’utilizzo del modificatore +%F. Tanto per intenderci


zarrelli@moveaway:~$ date +%F
2008-02-23
zarrelli@moveaway:~$#

potrebbe essere interessante, come potreste trovare più piacevole un


zarrelli@moveaway:~$ date +%A.%d.%B.%Y
sabato.23.febbraio.2008
zarrelli@moveaway:~$

Rimane a voi giocare con i modificatori del comando date (man date per consultare il manuale in linea) e trovare la soluzione con la quale vi sentite più a vostro agio.

Ovviamente, al posto di richiamare direttamente l’utility date, basterà recuperare il valore della variabile DATA (ovvero il percorso all’utility date) anteponendole il segno di dollaro, e passandole il modificatore.


DATE=$($DATA +%F)

Quindi, DATE avrà come valore l’output del comando /bin/date +%F.

La seconda riga ha un significato molto simile. Solamente, in questo caso date è forzato a mostrare la data di 15 giorni precedenti alla data corrente (–date=’15 days ago’), formattandone l’output nel formato numerico anno-mese-giorno. Da notare che i due modificatori +%F e +’%Y-%m-%d’, sono equivalenti.

Nelle due righe seguenti, semplicemente diamo forma ai nomi di due file:

  1. uno, assegnato alla variabile ARCHIVE, verrà utilizzato per contenere il backup del file system
  2. l’altro, assegnato alla variabile ARCHIVE_MYSQL, racchiuderà il dump del database MySQL.

Da notate che il nome di ognuno è creato preponendo a una parte fissa il contenuto della variabile DATE: in questo modo, ogni giorno verranno creati due file i cui nomi rimanderanno direttamente alla data di creazione, rendendoli facilmente riconoscibili.

Continuiamo con il seguente blocco di variabili


BACKUP_SPOOL="/var/spool/backup"
BACKUP_DIR="/usr/local/apache /usr/local/mysql/ /var/mysql /var/lib/awstats /etc/ $BACKUP_SPOOL/$MYSQL_BACKUP_FILE"
BACKUP_EXCLUDE_DIR="/usr/local/apache/tmp/ /usr/local/apache/htdocs/data/videos/ /var/spool/backup /etc/passwd /etc/shadow"

La prima riga indica una variabile nella quale viene conservato il valore del percorso a una directory di spool, ovvero la directory nella quale verranno conservati gli archivi contenenti i backup.

La seconda riga contiene l’elenco delle directory da sottoporre all’utility di backup. Da notare che uno dei percorsi non è indicato direttamente, ma richiamando i valori delle variabili BACKUP_SPOOL e MYSQL_BACKUP_FILE, concatenandoli e frapponendo una slash (/). Espandendo le variabili concatenate


$BACKUP_SPOOL/$MYSQL_BACKUP_FILE

si avrà quindi l’indirizzo:


/var/spool/backup/$DATE-mysql.nome-del-server.com.backup.sql

In pratica, interpretando la riga, si può facilmente comprendere che nel backup totale di tutti i file si vuole includere espressamente anche il dump giornaliero del database MySQL. Quello e solo quello, anche se ve ne fossero di precedenti nella stessa directory /var/spool/backup.

La terza indica di quali directory e file non si vuole avere una copia.

In effetti, è inutile avere una copia delle varie tmp, spool il cui contenuto è per sé temporaneo, di directory “pesanti”, magari contenenti video di famiglia che si possono facilmente recuperare a casa, ma che incrementerebbero notevolmente la dimensione file di backup.

Ragionamento un po’ piu’ complesso per passwd e shadow: in un file di backup in chiaro che passa per un protocollo non criptato, meglio non infilare dati sensibili, a meno di crittare direttamente l’archivio creato, prima di trasferirlo.

Ora, è il momento del terzultimo blocco di variabili:


BACKUP_MACRO="backup"
RM=$(which rm)
TAR=$(which tar)
TAR_OPTS="cvzf"
TAR_REMOVE="--remove-files -cvzf"
FTP=$(which ftp)
FIND=$(which find)
ECHO=$(which echo)

BACKUP_MACRO viene utilizzata per contenere il nome della macro che andremo a definire a livello di client FTP, il che ci consentirà di automatizzare il trasferimento dei dati. Non andiamo oltre, per ora, approfondiremo l’argomento fra poco.

Il resto è composto da sostituzioni di comando, cui si affiancano variabili che contengono le opzioni da passare ad alcuni di questi comandi. Attenzione. A volte conviene inglobare le opzioni nella stessa variabile che contiene il comando stesso, come in DATE, altre volte, specialmente quando la stessa utility debba essere utilizzata in modi differenti, come TAR, è più utile separare le opzioni dall’eseguibile, per poter comporre più facilmente differenti righe di comando.

Penultimo blocco di intestazione:


MYSQL_DUMP=$(which mysqldump)
MYSQL_OPTS="--socket=/usr/local/apache/mysql.sock/mysql.sock --all-databases --user=nome_utente --password=password_di_accesso"
MYSQL_BACKUP_FILE="$DATE-mysql.nome-del-server.com.backup.sql"

Beh, a questo punto dovrebbe esservi chiaro cosa si intende fare. Si recupera il percorso all’utility necessaria a creare il dump dei database contenuti in MySQL, si predispongono le opzioni necessarie per accedere al server db (da notare che in questo caso, essendo il server MySQL in locale, si indica una bella socket a file, tanto per andare più veloci, altrimenti si può indicare l’indirizzo IP corrispondente). Infine si predispone un file in cui riversare il dump del database, intestandolo con la data in cui questo verrà creato.

Ultima informazione contenuta nell’intestazione:


SERVER="indirizzo-del-server-di-appoggio"

Nulla di particolare: si tratta dell’hostname, o dell’indirizzo IP (consiglio quest’ultimo), del server FTP sul quale appoggeremo i file di backup.

La parte elaborativa dello script

Passiamo ora all’ultima parte dello script, quella elaborativa, quella, insomma, che compie il lavoro sporco.

Avendo creato un’intestazione che raccoglie tutti i dati essenziali, “importante” quindi anche come peso, la parte di processazione sarà, al contrario, molto leggera, anche se meno espressiva. Leggiamola e commentiamola riga per riga:


$MYSQL_DUMP $MYSQL_OPTS > $BACKUP_SPOOL/$MYSQL_BACKUP_FILE

La prima operazione compiuta dal nostro script consisterà in un backup del database. Richiamando i contenuti delle variabili sulla riga, verrà richiamata l’utility mysqldump, cui saranno passate varie opzioni. L’output del programma, ovvero il dump dei database, verrà rediretto (>) sul file il cui percorso è indicato dalla seconda parte della riga di comando, creato dinamicamente accedendo ai valori delle variabili di riferimento, in parte generati dall’output del comando date. In pratica, in /var/spool/backup avrete un file che inizia con la data del giorno in cui avete creato il dump e termina con -mysql.nome-del-server.com.backup.sql.


$TAR $TAR_REMOVE $BACKUP_SPOOL/$ARCHIVE_MYSQL $BACKUP_SPOOL/$MYSQL_BACKUP_FILE

Nulla di particolare: viene creato un archivio compresso del file contenente il dump dei database. Una volta terminata l’archiviazione, il file .sql non compresso viene cancellato.


$FIND $BACKUP_EXCLUDE_DIR > $BACKUP_SPOOL/IGNORE.LST

Quando si esegue l’archiviazione di una directory, normalmente l’utility tar seleziona tutti i file in essa contenuti, tutte le sotto directory e tutti i file nelle sotto directory.

Non sempre questo può essere ciò che si vuole.

Per esempio, si vuole eseguire il backup della directory /etc, ma non di /etc/passwd e /etc/shadow, oppure di /home/utente ma non di /home/utente/.wine. Magari si vuole avere un backup dell proprio sito /usr/local/apache/htdocs/ ma non della directory /usr/local/apache/htdocs/data/videos/ nella quale sono contenuti i videocast ospitati dal vostro sito, che renderebbero inutilmente pesante il file di backup.

Che fare?

Semplice, basta chiedere all’utility find di elencare tutti i percorsi ai file e alle directory che non si vogliono archiviare, per poi salvare il suo output in una black list che verrà passata a tar, in modo che li ignori.


$TAR $TAR_OPTS $BACKUP_SPOOL/$ARCHIVE -X $BACKUP_SPOOL/IGNORE.LST $BACKUP_DIR

Ed ecco tar all’opera: archivierà tutti i file contenuti nelle directory indicate (e da notare che le sotto directory, così come le directory, sono anch’esse dei file), ignorando (-X) quelli contenuti in IGNORE.LST.


$ECHO "\$ $BACKUP_MACRO $RM_DATE" | $FTP $SERVER

Non rimane che spostare via FTP gli archivi creati. La riga qui sopra vi sembra incomprensibile? Già. Per ora diciamo che l’utility ftp viene richiamata indicandole il server il cui indirizzo è contenuto in SERVER e passandole una macro che si occuperà di caricare i nuovi archivi e, per sicurezza, di ricavare dello spazio, cancellando sul server remoto gli archivi più vecchi della data indicata in RM_DATE.

Vedremo tra poco più in dettaglio come si costruisce una macro FTP. Per ora, basti sapere che entra in gioco il file .netrc, contenuto nella directory home dell’utente con il quale viene lanciato lo script, il quale consente di passare all’utility non solo le credenziali di login al server FTP ma anche una serie di comandi necessari ad automatizzare le procedure di trasferimento.


$RM $BACKUP_SPOOL/$ARCHIVE $BACKUP_SPOOL/$ARCHIVE_MYSQL

Siamo arrivati alla fine dello script. Facciamo un po' di pulizie, cancellando dalla spool gli archivi che abbiamo appena spostato sul server remoto.

Terminato lo script principale, non rimane che scrivere qualche riga ancora, per automatizzare le operazioni di trasferimento: è tempo di affrontare le macro FTP.

La macro FTP

Il "gioco" dell'FTP ruota tutto attorno a un file, .netrc, posto nella directory dell’utente utilizzato per eseguire lo script.

Come al solito, vediamone prima l’intera sequenza di comandi, per poi commentarla passo passo:


machine localhost
login caricamento
password caricapassword

macdef backup
binary
lcd /var/spool/backup
cd archivio_backup
mput *.tgz
delete $1-nome-del-server.backup.tgz
delete $1-mysql.nome-del-server.backup.tgz
quit

Iniziamo con la prima riga:


machine localhost

Possiamo definire questo come il marcatore d’inizio di un contenitore di istruzioni. Quando viene lanciato, FTP cerca nel file .netrc, l’istruzione machine e compara il valore che la segue con l’argomento che le è stato fornito, sulla riga di comando, come indirizzo del server remoto cui collegarsi. Se l’uguaglianza è riscontrata, FTP processerà tutte le rimanenti istruzioni, fino a fine file o alla seguente istruzione machine.

Detto in soldoni, machine deve riportare lo stesso indirizzo contenuto nella variabile SERVER . Volendo, si potrebbero avere più blocchi machine per eseguire login differenti su macchine diverse.


login caricamento
password caricapassword

Qui inserite la login e la password del vostro account FTP sul server remoto. Niente di speciale.


macdef backup

Ecco iniziare la parte più interessante del file. Questo marcatore definisce una macro, il cui nome deve essere indicato sulla stessa riga. In questo caso, si chiamerà backup. Le righe che seguiranno questa dichiarazione iniziali saranno considerati come facenti parte della macro, fino a che non verrà incontrato un carriage return, o due caratteri di newline consecutivi. In pratica, per terminare una macro, dovete semplicemente lasciare una riga vuota alla fine.

Vi è un limite di 16 macro e 4096 caratteri in totale, per tutto il file .netrc, quindi non sprecateli. Da ricordare che esistono due caratteri speciali:

  1. $ Seguito da uno o più numeri viene interpretato come il corrispondente argomento sulla riga di comando che ha richiamato la macro. Se $ viene fatto seguire da una i, la macro viene ciclata e al primo “giro”, i viene sostituito con il primo argomento della riga di comando che ha richiamato la macro, al secondo, con il secondo argomento e così di seguito.
  2. \ Ha la classica funzione di escape, e quindi qualsiasi carattere che venga preceduto da \ non verrà interpretato.


binary

Ci assicuriamo che il trasferimento dei file avvenga in modalità binaria.


lcd /var/spool/backup

Ci spostiamo, sul server remoto, nella directory nella quale vogliamo caricare gli archivi.


cd archivio_backup

Ci spostiamo, sul server locale (quello su cui abbiamo creato gli archivi), nella directory di spool nella quale abbiamo creato i file .tgz.


mput *.tgz

Magia del globbing. In pratica, usiamo * per istruire il client FTP affinché carichi sul server remoto tutti i file .tgz presenti in /var/spool.


delete $1-nome-del-server.backup.tgz

Ora, ricordate la penultima istruzione dello script? Diamoci nuovamente un’occhiata:


$ECHO "\$ $BACKUP_MACRO $RM_DATE" | $FTP $SERVER

Cosa significa questa stringa? Semplicemente, si richiama il client FTP, passandogli come argomento l’indirizzo del server cui collegarsi e, in pipe (|) gli si fornisce il nome della macro da richiamare e la data con la quale comporre il nome dei file da cancellare.

Fermiamoci un breve inciso.

In realtà, il nome della macro viene accettato da FTP nel formato:


$ nome_macro

Quindi, nel nostro caso, il nome della macro accettato da FTP è:


$ backup

che è ben diverso da:

$BACKUP_MACRO

Quest’ultimo, infatti non è altro che l’istruzione per richiamare il contenuto della variabile BACKUP_MACRO, quindi, la precedente riga, si deve leggere:


backup

Il client FTP, però, accetta il nome della macro, solo se preceduta da $$ deve essere passato in modo che non ci siano equivoci, che non possa essere interpretato all’interno della macro, quindi va preceduto dal carattere speciale \ e inviato in questa forma come argomento da passare al client.

La precedente riga, quindi, interpretata correttamente, operando la giusta sostituzione di variabili, nel sistema utilizzato per questi esempi si risolve in:


/bin/echo "\$ backup 2008-02-09" | /usr/bin/ftp indirizzo-del-server-di-appoggio

e quindi la precedente riga di macro:


delete $1-nome-del-server.backup.tgz

interpretata diventa:


delete 2008-02-09-nome-del-server.backup.tgz

dato che 2008-02-09 è il primo argomento ($ privo di escape), passato alla riga di comando che ha invocato la macro.

Da notare che si è deciso di tenere una quindicina di giorni di archivi, ma l’effettivo arco di ritenzione è condizionato solo dallo spazio a disposizione, quindi sta a voi decidere quanto, in base ai vostri personali criteri.


delete $1-mysql.nome-del-server.backup.tgz

Qui vale il discorso fatto per la precedente istruzione. Cambia solo la parte finale del nome del file da cancellare, in questo caso l’archivio contenente il dump del database.


quit

Finito. Trasferiti i file, si chiude la connessione al server.

Copiate il blocco di istruzioni appena viste in un file .netrc e ponetelo nella home dell’utente che intendete utilizzare per eseguire lo script.

Modificate le proprietà del file con il comando:


chmod 600 .netrc

altrimenti vi ritroverete con un FTP ricalcitrante. Occhio anche ai permessi e proprietario del file contenente lo script, mai lasciarlo eseguibile o modificabile da altri che non sia l’utente da voi scelto per eseguire questo compito.

Ricordatevi, infine, di terminare il blocco di macro, in .netrc con una riga vuota.

Conclusioni

Ciò che abbiamo visto è un esempio di come, sfruttando gli automatismi messi a disposizione dalle utility e dai comandi presenti in un sistema Unix sia possibile automatizzare compiti anche complessi, ma ripetitivi.

Ora, se prendiamo il file contenente lo script appena creato, lo rendiamo eseguibile e lo spostiamo nella cartella cron.daily, avremo un sistema automatizzato che tutte le notti archivierà i dati e li sposterà su un server remoto, in modo che avremo sempre a disposizione un backup completo dei file che ci interessa preservare.

Certo, non si tratta di un sistema sofisticato, che consente di creare backup totali e incrementali, o meglio, ci vorrebbe ancora un po’ di lavoro perché possa farlo, ma il suo lavoro lo esegue velocemente e senza troppi fronzoli.

Si può migliorare?

Certo.

Quello che vi ho proposto è solo uno scheletro di base. Intendiamoci, già così funziona senza problemi, ma si potrebbe implementare un’ulteriore struttura di controllo, che verifichi l’effettiva creazione dei file di archivio prima di trasferirli, che ci avvisi se la connessone FTP non è disponibile, insomma, che ci dia un feedback sul buon esito di tutta l’operazione.

In realtà, non è molto difficile implementare dei controlli. Potrete farlo tranquillamente voi, oppure potrebbe essere l’argomento di un prossimo post.

Buon lavoro!

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.