Repository 32bit  Forum
Repository 64bit  Wiki

Organizzare un backup completo: differenze tra le versioni

Da Slacky.eu.
 
(Script)
Riga 8: Riga 8:
#!/bin/bash
#!/bin/bash
# The bash/sh interpreter
# The bash/sh interpreter
# ***************************************************************************************
+
# =======================================================================================
# questo script ha lo scopo di organizzare un backup completo di
# questo script ha lo scopo di organizzare un backup completo di
# un path liberamente definibile. Lo script organizza i dati in
# un path liberamente definibile. Lo script organizza i dati in
# immagini iso di grandezza definibile e le masterizza man mano.
# immagini iso di grandezza definibile e le masterizza man mano.
# ***************************************************************************************
+
# =======================================================================================
# =======================================================================================
# =======================================================================================
Riga 22: Riga 22:
# se mi chiedi aiuto o non sai come usarmi, ti spiego
# se mi chiedi aiuto o non sai come usarmi, ti spiego
echo "$(basename $0) v2.0
+
cat <<end-of-help
Questo script ha lo scopo di organizzare un backup completo di
+
$(basename $0) v3.0
un path liberamente definibile. Lo script organizza i dati in
+
Questo script ha lo scopo di organizzare un backup completo di un path liberamente
immagini iso di grandezza definibile e le masterizza man mano."
+
definibile. Lo script organizza i dati in immagini iso di grandezza data.
echo "Utilizzo:
+
Utilizzo:
$(basename $0) [opzioni] [specifiche]
+
$(basename $0) [opzioni]
OPZIONI:
OPZIONI:
-h, --help: stampa questo help ed esce.
+
-h: stampa questo help ed esce;
-c, --conf: mostra la configurazione contenuta all'interno
+
-c: mostra la configurazione contenuta all'interno del file di configurazione;
del file ~/$backfile, se esiste.
+
-M dim: imposta a "dim" MB la dimensione massima dell'immagine ISO;
-f, --file: effettua il backup con le impostazioni contenute
+
-I dim: imposta a "dim" MB la dimensione preferita dell'immagine ISO, per default pari
all'interno del file ~/$backfile, se esiste.
+
alla dimensione massima;
-s, --save: effettua il backup con le impostazioni che gli sono
+
-O dim: imposta a "dim" MB la dimensione ottimale delle directory;
fornite di seguito
+
-p path: effettua il backup della directory "path";
-r, --resume: riprende l'ultimo backup effettuato.
+
-e list: esclude dal backup le directory contenute in "list";
--quiet: quando è data questa opzione, le immagini ISO sono
+
-n num: l'indice progressivo di backup parte da "num";
create senza soluzione di continuità.
+
-q: modalità quiet, le immagini ISO sono create senza soluzione di continuità;
  +
-t: modalità test, crea la lista di backup ed esce;
  +
-r path: effettua il resume dell'ultimo backup effettuato, essendo "path" la directory
  +
creata nello scorso backup;
  +
-f file: effettua il backup con le impostazioni contenute all'interno
  +
del file "file";
  +
-i date: modalità incrementale, backup di tutti i file più recenti di "date";
  +
-s opt: opzioni di ordinamento:
  +
> alph, ordinamento alfabetico
  +
> num, ordinamento numerico
  +
> inum, ordinamento numerico inverso (default)
  +
-l name: imposta a "name" il nome dell'immagine ISO, aggiungendo un numero progressivo
  +
-z: modalità compressa, ogni directory e file è compresso in un archivio tar.bz2
  +
-o: modalità ottimizzata, ogni immagine ISO è riempita fino alla sua massima
  +
capienza, stipando file via via più piccoli
SPECIFICHE:
+
AVVERTENZE:
Se è utilizzata la funzione -s, allora devono essere dati i seguenti dati
+
--> Le dimensioni fornite devono essere tali che optdim << isodim < maxdim
in quest'ordine:
+
--> È possibile che una directory da escludere, se posta all'interno di una directory
$(basename $0) -s backup={backdir} exclude={excdir} optdim={optdim}
+
di dimensione minore di optdim MB, sia comunque inclusa
isodim={isodim} maxdim={maxdim}
+
--> Non sono inclusi nel set di backup i link simbolici
+
--> È sempre consigliabile verificare, mediante l'opzione -t, cosa lo script andrà
backdir: path completo della directory da organizzare per il backup
+
effettivamente a salvare
excdir: nomi delle sotto-directory da escludere, separati da |
 
optdim: dimensione ottimale delle cartelle da comprimere
 
isodim: dimensione approssimativa finale dell'immagine ISO
 
maxdim: dimensione massima del supporto utilizzato
 
 
ovviamente deve risultare optdim << isodim < maxdim
 
 
Se è utilizzata la funzione -s, allora devono essere forniti i seguenti dati:
 
$(basename $0) -r {prev_path} {n}
 
 
prev_path: percorso completo della directory creata durante l'ultimo backup
 
n: indice dell'immagine ISO successiva all'ultime creata
 
"
 
  +
Se avete suggerimenti o avete trovato un bug, vi prego di comunicarmelo.
  +
tiferet dot angelo at tiscali dot it
  +
end-of-help
exit 0
exit 0
}
}
Riga 58: Riga 61:
# controllo se il file di configurazione esiste
# controllo se il file di configurazione esiste
preleva_conf
+
if [ "$BACKFILE_FLAG" -eq "1" ]; then
  +
preleva_conf newone
  +
elif [ "$RESUME_FLAG" -eq "1" ]; then
  +
preleva_conf resume
  +
else
  +
BACKFILE="no file, default configuration"
  +
fi
# stampo la configurazione
# stampo la configurazione
echo "*************************************************************************"
+
cat <<end-of-configuration
echo "Sarà effettuato il backup completo della directory $backdir"
+
=========================================================================
echo "La dimensione dell'immagine ISO è impostata a $isodim MB"
+
$(basename $0) v3.0 - configurazione contenuta nel file:
echo "La dimensione ottimale è impostata a $optdim MB"
+
--> $BACKFILE
echo "La dimensione dei supporti è impostata a $maxdim MB"
+
=========================================================================
echo "*************************************************************************"
+
> Sarà effettuato il backup completo della directory: $BACKDIR
+
> La dimensione dell'immagine ISO è impostata a: $ISODIM MB
  +
> La dimensione ottimale è impostata a: $OPTDIM MB
  +
> La dimensione dei supporti è impostata a: $MAXDIM MB
  +
========================================================================="
  +
end-of-configuration
exit 0
exit 0
  +
}
  +
  +
function tempname ()
  +
{
  +
# la funzione tempname serve per restituire in uscita un nome casuale
  +
STRING=$(mcookie)
  +
NAME=${STRING:0:LEN}
  +
NAME_TEMP=$TMP/$NAME.temp
  +
  +
while [ -e $NAME_TEMP ]; do
  +
STRING=$(mcookie)
  +
NAME=${STRING:0:LEN}
  +
NAME_TEMP=$NAME.temp
  +
done
  +
  +
echo $NAME_TEMP
}
}
Riga 74: Riga 93:
{
{
# la funzione preleva_conf serve per verificare, ove necessario, l'esistenza del
# la funzione preleva_conf serve per verificare, ove necessario, l'esistenza del
# file di configurazione e quindi di prelevare i valori corretti delle imnpostazioni
+
# file di configurazione e quindi di prelevare i valori corretti delle impostazioni
if [ ! -e ~/$backfile ]; then
+
# il comportamento della funzione cambia a seconda che le sia stato passato il comando
  +
# "newone" ovvero "resume"
  +
if [ ! -e $BACKFILE -a "$1" == "newone" ]; then
echo "Non esiste ancora un file di configurazione!"
echo "Non esiste ancora un file di configurazione!"
echo "Ne creerò uno di default, ma è opportuno controllarlo!"
echo "Ne creerò uno di default, ma è opportuno controllarlo!"
echo "backup_path :{please, insert path for directory to backup}:" > ~/$backfile
+
(
echo "iso_dimension :4200:" >> ~/$backfile
+
cat <<end-of-default-conf-file
echo "opt_dimension :1024:" >> ~/$backfile
+
backup_path :{please, insert path for directory to backup}:
echo "max_dimension :4400:" >> ~/$backfile
+
iso_dimension :$ISODIM:
echo "exclude_path :foo1|foo2|foo3:" >> ~/$backfile
+
opt_dimension :$OPTDIM:
exit 1
+
max_dimension :$MAXDIM:
  +
exclude_path :foo1,foo2,foo3:
  +
end-of-default-conf-file
  +
) > $BACKFILE
  +
exit $E_NO_BACKFILE
  +
elif [ ! -e $BACKFILE -a "$1" == "resume" ]; then
  +
echo "Spiacente, ma non è possibile effettuare il resume!"
  +
echo "Non è stato possibile trovare il file di resume:"
  +
echo "\"$BACKFILE\""
  +
echo "Controlla che esista e che sia leggibile"
  +
exit $E_NO_CONFFILE
else
else
backdir=$(grep 'backup' ~/$backfile | cut "-d:" -f2)
+
BACKDIR=$(grep 'backup_path' $BACKFILE | cut "-d:" -f2)
isodim=$(grep 'iso' ~/$backfile | cut "-d:" -f2)
+
ISODIM=$(grep 'iso_dimension' $BACKFILE | cut "-d:" -f2)
optdim=$(grep 'opt' ~/$backfile | cut "-d:" -f2)
+
OPTDIM=$(grep 'opt_dimension' $BACKFILE | cut "-d:" -f2)
maxdim=$(grep 'max' ~/$backfile | cut "-d:" -f2)
+
MAXDIM=$(grep 'max_dimension' $BACKFILE | cut "-d:" -f2)
excpath=$(grep 'exclude' ~/$backfile | cut "-d:" -f2)
+
EXCPATH=$(grep 'exclude_path' $BACKFILE | cut "-d:" -f2)
  +
LINE=$(grep 'line' $BACKFILE | cut "-d:" -f2)
return 0
return 0
fi
fi
}
}
function preleva_dati () # modificare in modo che l'utente debba inserire una sintassi del tipo variabile=valore
+
function corretta_sintassi ()
{
 
# la funzione preleva_dati serve per assegnare correttamente i parametri alle variabili
 
arg1=$(echo "$*" | egrep -o "backup=.*" | cut "-d=" -f2 | cut "-d " -f1)
 
arg2=$(echo "$*" | egrep -o "exclude=.*" | cut "-d=" -f2 | cut "-d " -f1)
 
arg3=$(echo "$*" | egrep -o "isodim=.*" | cut "-d=" -f2 | cut "-d " -f1)
 
arg4=$(echo "$*" | egrep -o "optdim=.*" | cut "-d=" -f2 | cut "-d " -f1)
 
arg5=$(echo "$*" | egrep -o "maxdim=.*" | cut "-d=" -f2 | cut "-d " -f1)
 
 
backdir=${arg1:-~}
 
excpath=${arg2:-""}
 
isodim=${arg3:-"4200"}
 
optdim=${arg4:-"1024"}
 
maxdim=${arg5:-"4400"}
 
}
 
 
function preleva_resume ()
 
{
 
# la funzione preleva_resume ha il compito di impostare correttamente i dati di backup
 
# relativi ad un backup precedentemente interrotto. Devono essere forniti:
 
# il percorso della directory temporanea del backup precedente e il numero progressivo
 
# del backup da eseguire
 
tempdir="$1"
 
n="$2"
 
 
# per evitare che siano ricreate le liste dei file e delle directory, imposto la
 
# variabile $work a "resume"
 
work="resume"
 
 
# prelevo i dati dell'ultimo backup
 
backdir=$(grep 'backup' $tempdir/$confile | cut "-d:" -f2)
 
isodim=$(grep 'iso' $tempdir/$confile | cut "-d:" -f2)
 
optdim=$(grep 'opt' $tempdir/$confile | cut "-d:" -f2)
 
maxdim=$(grep 'max' $tempdir/$confile | cut "-d:" -f2)
 
excpath=$(grep 'exclude' $tempdir/$confile | cut "-d:" -f2)
 
line=$(grep 'line' $tempdir/$confile | cut "-d:" -f2)
 
}
 
 
function se_corretta_sintassi ()
 
{
{
# la funzione se_corretta_sintassi verifica che sia stato dato il corretto numero e
# la funzione se_corretta_sintassi verifica che sia stato dato il corretto numero e
Riga 100: Riga 119:
# path inesistente?
# path inesistente?
if [ ! -e $backdir ]; then
+
if [ ! -e $BACKDIR ]; then
echo "Penso che tu abbia sbagliato ad indicarmi il percorso..."
echo "Penso che tu abbia sbagliato ad indicarmi il percorso..."
exit 1
+
return $E_BAD_PATH
# ordine sbagliato?
# ordine sbagliato?
elif [ $optdim -gt $isodim ]; then
+
elif [ $OPTDIM -gt $ISODIM ]; then
echo "La dimensione ottimale ($optdim MB) non può essere superiore"
+
echo "La dimensione ottimale ($OPTDIM MB) non può essere superiore"
echo "alla dimensione dell'immagine ISO ($isodim MB)."
+
echo "alla dimensione dell'immagine ISO ($ISODIM MB)."
exit 1
+
return $E_BAD_OPTDIM
elif [ $isodim -gt $maxdim ]; then
+
elif [ $ISODIM -gt $MAXDIM ]; then
echo "La dimensione dell'immagine ISO ($isodim MB) non può essere superiore"
+
echo "La dimensione dell'immagine ISO ($ISODIM MB) non può essere superiore"
echo "alla dimensione del supporto ($maxdim MB)."
+
echo "alla dimensione del supporto ($MAXDIM MB)."
exit 1
+
return $E_BAD_ISODIM
fi
fi
# creo il file config contenente le informazioni sul backup, per un evantuale resume
+
# creo il file config contenente le informazioni sul backup, per un eventuale resume
if [ "$work" != "resume" ]; then
+
if [ "$RESUME_FLAG" -eq "0" ]; then
echo "backup_path :$backdir:
+
(
iso_dimension :$isodim:
+
cat <<end-of-resume-file
opt_dimension :$optdim:
+
backup_path :$BACKDIR:
max_dimension :$maxdim:
+
iso_dimension :$ISODIM:
exclude_path :$excpath:" > $tempdir/$confile
+
opt_dimension :$OPTDIM:
  +
max_dimension :$MAXDIM:
  +
exclude_path :$EXCPATH:
  +
end-of-resume-file
  +
) > $TEMPDIR/$CONFILE
  +
fi
  +
  +
# controllo la validità del $REFTIME, se dato, ed in caso lo imposto ad una data arcaica
  +
# in modo da attivare il backup totale [yyyymmddHHMM]
  +
if [ "$INCREMENTAL_FLAG" -eq "0" ]; then
  +
REFTIME=197001010000
  +
fi
  +
  +
# controllo che $REFTIME sia effettivamente un numero almeno positivo....
  +
if [ "$REFTIME" -lt "0" ]; then
  +
echo "Spiacente, ma credo che ci sia qualche problema con la data di riferimento"
  +
echo "--> $REFTIME"
  +
return $E_BAD_REFTIME
  +
fi
  +
  +
# controllo che $REFTIME abbia le informazioni necessarie
  +
REFTIME_CHARS=$(echo -n $REFTIME | wc -m)
  +
if [ "$REFTIME_CHARS" -ne "12" ]; then
  +
echo "Spiacente, ma devi indicare anno, mese, giorno, ore e minuti"
  +
echo "della data di riferimento (yyyymmddHHMM)"
  +
return $E_SHORT_REFTIME
fi
fi
}
}
Riga 132: Riga 151:
# controllo che la directory $backdir non entri in un singolo supporto; in quel caso non
# controllo che la directory $backdir non entri in un singolo supporto; in quel caso non
# c'é bisogno di fare alcunché, altrimenti creo la lista delle sottodirectory, eliminando
# c'é bisogno di fare alcunché, altrimenti creo la lista delle sottodirectory, eliminando
# la prima riga che contiene proprio la $backdir
+
# la prima riga che contiene proprio la $BACKDIR
if [ "$totdim" -gt "$maxdim" ]; then
+
if [ "$TOTDIM" -gt "$MAXDIM" ]; then
du -k --max-depth 1 --exclude=.* $backdir | head -n -1 | sort -nr -o $kodir
+
du -k --time --time-style=+%Y%m%d%H%M --max-depth 1 $BACKDIR | \
  +
head -n -1 | sort $SORT_OPTS -o $KODIR
  +
find "$BACKDIR" -maxdepth 1 -type f -newer $TEMPDIR/$LIMENFILE \
  +
-printf "%k\t%CY%Cm%Cd%CH%CM\t%p\n" >> $SPAREFILES
else
else
echo "La directory $backdir ha un dimensione inferiore a quella di un singolo"
+
echo "errore!"
echo "supporto: $totdim KB < $maxdim KB. Pertanto non è necessario proseguire."
+
echo "La directory $BACKDIR ha un dimensione inferiore a quella di un singolo"
exit 0
+
echo "supporto: $TOTDIM KB < $MAXDIM KB. Pertanto non è necessario proseguire"
  +
exit $E_LITTLE_BACKDIR
  +
fi
  +
  +
# controllo che all'interno di $BACKDIR non vi siano file di dimensione maggiore
  +
# $MAXDIM, che non sarebbero mai salvati
  +
HUGEFILE=$(find $BACKDIR -type f -size +"$MAXDIM"k)
  +
if [ "$HUGEFILE" ]; then
  +
echo "Spiacente, ma i seguenti file:"
  +
echo $HUGEFILE
  +
echo "hanno una dimensione maggiore di $MAXDIM KB, pertanto non possono"
  +
echo "essere salvati. Eliminali o suddividili in altri più piccoli, poi"
  +
echo "riprendi l'operazione di backup."
  +
return $E_HUGEFILE
fi
fi
# se la directory da backuppare non entra in un singolo supporto,
# se la directory da backuppare non entra in un singolo supporto,
# allora è meglio scomporla in più sotto-directory.
# allora è meglio scomporla in più sotto-directory.
while [ "`cat $kodir`" ]; do
+
while [ -s $KODIR ]; do
read line1 < $kodir
+
EXCLUDE_FLAG=1
dirdim=$(echo $line1 | cut "-d " -f1)
+
read FIRST_LINE < $KODIR
dirname=$(echo $line1 | cut "-d " -f2-)
+
DIRDIM=$(echo $FIRST_LINE | cut "-d " -f1)
if [ "$dirdim" -gt "$optdim" ]; then
+
DIRTIME=$(echo $FIRST_LINE | cut "-d " -f2)
du -k --max-depth 1 "$dirname" | head -n -1 >> $kodir
+
DIRNAME=$(echo $FIRST_LINE | cut "-d " -f3-)
find "$dirname" -maxdepth 1 -type f -printf "%k\t%p\n" >> $sparefiles
+
# se la directory in esame è nell'insieme dei path da escludere o non è stata modificata
sed 1d $kodir | sort -nr -o $kodir
+
# prima del $REFTIME, la elimino e passo alla successiva. Similmente, il comando find
else
+
# trova soltanto i file più recenti del $LIMENFILE creato precedentemente con il comando
echo -e "$dirdim\t$dirname" >> $okdir
+
# touch e il timestamp indicato per default o dall'utente
sed 1d $kodir | sort -nr -o $kodir
+
while [ $EXCLUDE_FLAG -eq 1 ]; do
  +
EXCLUDE_FLAG=0
  +
for EXCLUDE in `echo $EXCPATH | xargs -d ,`; do
  +
if [ "$EXCLUDE" == "$DIRNAME" -o "$DIRTIME" -lt "$REFTIME" ]; then
  +
sed 1d $KODIR | sort $SORT_OPTS -o $KODIR
  +
# il controllo seguente è necessario per controllare che l'ultima
  +
# riga eliminata non abbia svuotato il file $KODIR, cosa che
  +
# non permetterebbe l'assegnazione delle variabili $DIRNAME,
  +
# $DIRTIME e $DIRDIM
  +
if [ -s $KODIR ]; then
  +
read FIRST_LINE < $KODIR
  +
DIRDIM=$(echo $FIRST_LINE | cut "-d " -f1)
  +
DIRTIME=$(echo $FIRST_LINE | cut "-d " -f2)
  +
DIRNAME=$(echo $FIRST_LINE | cut "-d " -f3-)
  +
EXCLUDE_FLAG=1
  +
else
  +
DIRDIM=0
  +
DIRTIME=0
  +
DIRNAME=""
  +
EXCLUDE_FLAG=0
  +
break
  +
fi
  +
fi
  +
done
  +
done
  +
# verificare che l'ultima voce del file $KODIR sia effettivamente messa in $OKDIR
  +
if [ -n "$DIRNAME" ]; then
  +
if [ "$DIRDIM" -gt "$OPTDIM" ]; then
  +
du -k --time --time-style=+%Y%m%d%H%M --max-depth 1 "$DIRNAME" | \
  +
head -n -1 >> $KODIR
  +
find "$DIRNAME" -maxdepth 1 -type f -newer $TEMPDIR/$LIMENFILE \
  +
-printf "%k\t%CY%Cm%Cd%CH%CM\t%p\n" >> $SPAREFILES
  +
sed 1d $KODIR | sort $SORT_OPTS -o $KODIR
  +
else
  +
echo -e "$DIRDIM\t$DIRTIME\t$DIRNAME" >> $OKDIR
  +
sed 1d $KODIR | sort $SORT_OPTS -o $KODIR
  +
fi
fi
fi
done
done
# elimino dai file $okdir e $sparefiles i path da escludere
+
# creo una copia di backup delle due liste, sempre che non siano file vuoti
if [ $excpath ]; then
+
if [ -s $OKDIR ]; then
sed -r /$excpath/d $okdir | sort -nr -o $okdir
+
cp $OKDIR $TEMPDIR/backup_$(basename $OKDIR)~
sed -r /$excpath/d $sparefiles | sort -nr -o $sparefiles
+
cat $OKDIR | sort $SORT_OPTS -o $OKDIR
  +
else
  +
echo "" > $TEMPDIR/backup_$(basename $OKDIR)~
fi
fi
# creo una copia di backup delle due liste
+
if [ -s $SPAREFILES ]; then
cp $okdir $tempdir/backup_$(basename $okdir)~
+
cp $SPAREFILES $TEMPDIR/backup_$(basename $SPAREFILES)~
cp $sparefiles $tempdir/backup_$(basename $sparefiles)~
+
cat $SPAREFILES | sort $SORT_OPTS -o $SPAREFILES
  +
else
  +
echo "" > $TEMPDIR/backup_$(basename $SPAREFILES)~
  +
fi
# conto di quante linee siano composti i due elenchi e sommo i risultati. Il totale
# conto di quante linee siano composti i due elenchi e sommo i risultati. Il totale
# costituisce il numero massimo di iterazioni che si può compiere per creare una
# costituisce il numero massimo di iterazioni che si può compiere per creare una
# singola immagine ISO, quindi scrivo il risultato nel file $confile
# singola immagine ISO, quindi scrivo il risultato nel file $confile
local dirlines=$(wc -l $okdir | cut "-d " -f1)
+
if [ -s $OKDIR ]; then
local filelines=$(wc -l $sparefiles | cut "-d " -f1)
+
local DIRLINES=$(wc -l $OKDIR | cut "-d " -f1)
let "line=$dirlines+$filelines"
+
else
echo "line :$line:" >> $tempdir/$confile
+
local DIRLINES=0
  +
fi
return
+
if [ -s $SPAREFILES ]; then
  +
local FILELINES=$(wc -l $SPAREFILES | cut "-d " -f1)
  +
else
  +
local FILELINES=0
  +
fi
  +
let "LINE=$DIRLINES+$FILELINES"
  +
echo "line :$LINE:" >> $TEMPDIR/$CONFILE
  +
  +
return 0
}
}
function se_entra ()
+
function entra ()
{
{
# la funzione se_entra ha il compito di verificare che il primo elemento dell'elenco
# la funzione se_entra ha il compito di verificare che il primo elemento dell'elenco
Riga 184: Riga 203:
# prendo la lista che mi viene passata
# prendo la lista che mi viene passata
local list="$1"
+
local LIST="$1"
# leggo la prima riga, ossia la directory (o file) più grande
# leggo la prima riga, ossia la directory (o file) più grande
if [ -s $list ]; then
+
if [ -s $LIST ]; then
local line1
+
local FIRST_LINE
read line1 < $list
+
read FIRST_LINE < $LIST
else
else
return 1
return 1
fi
fi
dirdim=$(echo $line1 | cut "-d " -f1)
+
DIRDIM=$(echo $FIRST_LINE | cut "-d " -f1)
# verifico lo spazio disponibile e dunque se la directory (o file) può entrare
# verifico lo spazio disponibile e dunque se la directory (o file) può entrare
local busydim=$(du -k --max-depth 0 $isodir | cut -f1)
+
local BUSYDIM=$(du -k --max-depth 0 $ISODIR | cut -f1)
# let "busydim=1024*100*$i"
+
local FREEDIM
local freedim
+
let "FREEDIM=$MAXDIM-$BUSYDIM"
let "freedim=$isodim-$busydim"
+
if [ "$DIRDIM" -le "$FREEDIM" ]; then
if (( $dirdim <= $freedim )); then
 
return 0
return 0
  +
elif [ "$OPTIMIZE_FLAG" -eq "1" ]; then
  +
sed 1d $LIST > $FILETEMP
  +
mv -f $FILETEMP $LIST
  +
echo $FIRST_LINE >> $LIST
  +
return 1
else
else
sed 1d $list > $filetemp
 
mv -f $filetemp $list
 
echo $line1 >> $list
 
return 1
return 1
fi
fi
}
}
function comprimi ()
+
function immagazzina ()
{
{
# la funzione "comprimi" ha la funzione di comprimere in un archivio .tar.bz2 la directory
# la funzione "comprimi" ha la funzione di comprimere in un archivio .tar.bz2 la directory
Riga 216: Riga 237:
# prendo la lista che mi viene passata
# prendo la lista che mi viene passata
local list="$1"
+
local LIST="$1"
# leggo la prima riga, ossia la directory (o file) più grande
# leggo la prima riga, ossia la directory (o file) più grande
local line1
+
local FIRST_LINE
read line1 < $list
+
read FIRST_LINE < $LIST
local dirpath=$(echo $line1 | cut "-d " -f2-)
+
local DIRPATH=$(echo $FIRST_LINE | cut "-d " -f3-)
# creo il nome dell'archivio
+
# procedo al salvataggio, differente a seconda che io debba comprimere oppure no
archname="$(echo $dirpath | sed s:$backdir/::g | sed s:/:_:g | sed s:" ":_:g)"
+
if [ "$ZIP_FLAG" -eq "1" ]; then
+
# creo il nome dell'archivio compresso, se necessario
# comprimo la directory più grande
+
ARCHNAME="$(echo $DIRPATH | sed s:$BACKDIR/:backup:g | sed s:/:_:g | sed s:" ":_:g)"
echo -n " $(basename "$dirpath")..."
+
# comprimo la directory più grande
if se_compresso "$(basename "$dirpath")"; then
+
echo -n " $(basename "$DIRPATH"), "
tar -cvjf $isodir/$archname.tar.bz2 "$dirpath" >> $tempdir/tar_output 2>&1
+
if ! compresso "$(basename "$DIRPATH")"; then
# touch $isodir/$(basename $dirpath).tar.bz2
+
echo -n "comprimo..."
else
+
tar -cvjf $ISODIR/$ARCHNAME.tar.bz2 "$DIRPATH" >> $TEMPDIR/tar_output 2>&1
tar -cvf $isodir/$archname.tar "$dirpath" >> $tempdir/tar_output 2>&1
+
else
# touch $isodir/$(basename $dirpath).tar
+
echo -n "già compresso..."
  +
tar -cvf $ISODIR/$ARCHNAME.tar "$DIRPATH" >> $TEMPDIR/tar_output 2>&1
  +
fi
  +
elif [ "$ZIP_FLAG" -eq "0" ]; then
  +
# prendo l'albero delle directory sotto cui sta la directory o il file in esame e lo
  +
# ricreo in $ISODIR, a meno che non esiste già e.g. nel caso di sottodirectory o nel
  +
# caso in cui stia tentando di creare la cartella .
  +
echo -n " $(basename "$DIRPATH")..."
  +
DIRTREE=$(dirname "$DIRPATH")
  +
if [ ! -e $ISODIR/$DIRTREE ]; then
  +
mkdir -p "$ISODIR/$DIRTREE"
  +
fi
  +
# quindi copio la directory o il file in esame in $ISODIR/$DIRTREE
  +
cp -a "$DIRPATH" "$ISODIR/$DIRTREE"
fi
fi
# cancello la prima riga dalla lista
# cancello la prima riga dalla lista
sed 1d $list > $filetemp
+
sed 1d $LIST > $FILETEMP
mv -f $filetemp $list
+
mv -f $FILETEMP $LIST
return 0
return 0
}
}
function se_compresso ()
+
function compresso ()
{
{
# la funzione se_compresso verifica se l'argomento passato è già stato compresso e
# la funzione se_compresso verifica se l'argomento passato è già stato compresso e
# restituisce 1 o 0 a seconda che sia stato o no compresso.
# restituisce 1 o 0 a seconda che sia stato o no compresso.
local file="$1"
+
local FILE="$1"
# con egrep verifico se nel nome del file sia contenuta un'estensione tipica dei
# con egrep verifico se nel nome del file sia contenuta un'estensione tipica dei
# formati compressi
# formati compressi
local zip=$(echo $file | egrep .'\<tar\>|\<rar\>|\<zip\>|\<gz\>|\<bz2\>|\<tgz\>|\<iso\>')
+
local ZIP=$(echo $FILE | egrep .'\<tar\>|\<rar\>|\<zip\>|\<gz\>|\<bz2\>|\<tgz\>|\<iso\>')
# restituisco il valore opportuno
# restituisco il valore opportuno
if [ "$zip" ]; then
+
if [ "$ZIP" ]; then
return 1
 
else
 
return 0
return 0
  +
else
  +
return $E_NO_ZIPPED_FILE
fi
fi
}
}
function se_pieno ()
+
function pieno ()
{
{
# la funzione se_pieno verifica che la cartella $isodir non abbia raggiunto la dimensione
# la funzione se_pieno verifica che la cartella $isodir non abbia raggiunto la dimensione
Riga 267: Riga 290:
# raggiunto o no tale limite
# raggiunto o no tale limite
local busydim=$(du -k --max-depth 0 $isodir | cut -f1)
+
local BUSYDIM=$(du -k --max-depth 0 $ISODIR | cut -f1)
# let "busydim=1024*100*$i"
 
if (( $busydim >= $isodim )) || (( $k >= $line )); then
+
if [ "$BUSYDIM" -ge "$ISODIM" -o "$K" -ge "$LINE" ]; then
k=0
+
K=0
return 1
 
else
 
return 0
return 0
  +
else
  +
return $E_NO_FULL_ISODIR
fi
fi
Riga 281: Riga 306:
# $isodir e successivamente attende verifica che la dimensione finale sia inferiore al
# $isodir e successivamente attende verifica che la dimensione finale sia inferiore al
# limite di capienza del supporto
# limite di capienza del supporto
mkisofs -r -V $(basename $isoname .iso) -o $imgdir/$isoname $isodir >> $tempdir/"$isoname"_output 2>&1
+
mkisofs -r -V $ISOLABEL -o $IMGDIR/$ISONAME $ISODIR >> $TEMPDIR/"$ISONAME"_output 2>&1
# prima di proseguire, controllo che l'immagine esista
+
# prima di proseguire, controllo che l'immagine esista e che abbia dimensione non nulla
if [ -e $imgdir/$isoname ]; then
+
if [ -e $IMGDIR/$ISONAME -a -s $IMGDIR/$ISONAME ]; then
local imgdim=$(du -k $imgdir/$isoname | cut -f1)
+
local IMGDIM=$(du -k $IMGDIR/$ISONAME | cut -f1)
else
+
elif [ ! -e $IMGDIR/$ISONAME ]; then
echo "=========================================================================="
echo "=========================================================================="
echo "Per qualche strano motivo, l'immagine non è stata creata."
echo "Per qualche strano motivo, l'immagine non è stata creata."
Riga 293: Riga 318:
echo "storto e riprendi con \"$(basename $0) --resume\""
echo "storto e riprendi con \"$(basename $0) --resume\""
echo "=========================================================================="
echo "=========================================================================="
exit 1
+
exit $E_ISO_CREATION_FAILED
  +
elif [ ! -s $IMGDIR/$ISONAME ]; then
  +
echo "=========================================================================="
  +
echo "Per qualche strano motivo, l'immagine creata ha dimensione nulla,"
  +
echo "probabilmente perché esiste un file singolo di dimensioni superiori"
  +
echo "a quelle del singolo supporto."
  +
echo ""
  +
echo "Mi dispiace, ma il backup si interrompe qui; controlla cosa è andato"
  +
echo "storto e riprendi con \"$(basename $0) --resume\""
  +
echo "=========================================================================="
  +
exit $E_NULL_ISODIM
fi
fi
# riordino per dimensione le liste dei file e delle directory
+
# riordino le liste dei file e delle directory e aggiorno le copie di backup delle liste
cat $okdir | sort -nr -o $okdir
+
if [ -s $OKDIR ]; then
cat $sparefiles | sort -nr -o $sparefiles
+
cat $OKDIR | sort $SORT_OPTS -o $OKDIR
  +
cp -f $OKDIR $TEMPDIR/backup_$(basename $OKDIR)~
  +
fi
# aggiorno le copie di backup delle liste
+
if [ -s $SPAREFILES ]; then
cp -f $okdir $tempdir/backup_$(basename $okdir)~
+
cat $SPAREFILES | sort $SORT_OPTS -o $SPAREFILES
cp -f $sparefiles $tempdir/backup_$(basename $sparefiles)~
+
cp -f $SPAREFILES $TEMPDIR/backup_$(basename $SPAREFILES)~
  +
fi
# per sicurezza, controllo che la dimensione effettiva dell'immagine sia inferiore al
# per sicurezza, controllo che la dimensione effettiva dell'immagine sia inferiore al
# limite massimo
# limite massimo
if [ "$imgdim" -le "$maxdim" ]; then
+
if [ "$IMGDIM" -le "$MAXDIM" ]; then
return 0
return 0
else
else
return 1
+
return $E_BIG_ISODIM
fi
fi
}
}
Riga 320: Riga 345:
# inizio programma principale
# inizio programma principale
# =======================================================================================
# =======================================================================================
# inizializzo variabili di path per comandi non residenti nel path di base
 
otbin=~/bin
 
# inizializzo le variabili $n e $tempdire quelle non dipendenti da queste due.
+
# inizializzo le variabili $n e $tempdir e quelle non dipendenti da queste due
# Le altre devono essere inizializzate dopo che si è scelta la funzione da utilizzare
+
# le altre devono essere inizializzate dopo che si è scelta la funzione da utilizzare
k=0 # indice riempimento
 
m=0 # indice file multipli
 
n=1 # indice nome backup
 
# i=0 # indice di riempimento virtuale
 
tempdir=~/tmp/$($otbin/tempname) # directory temporanea
 
imgdir=~/backup # directory delle immagini ISO
 
filetemp=~/tmp/$($otbin/tempname) # file temporaneo
 
confile=config # file di resume
 
backfile=".backntar.conf" # file di configurazione
 
# prelevo la funzione da effettuare, dal primo argomento
+
# indici
funzione="$1"
+
# {
  +
K=0 # indice riempimento
  +
M=0 # indice file multipli
  +
N=1 # indice nome backup
  +
LEN=6 # lunghezza stringa casuale
  +
# }
# controllo che mi sia stato ordinato di procedere in modalità "quiet", ossia creando
+
# codici di errore
# tutte le immagini ISO di seguito
+
# {
quiet=$(echo "$*" | grep quiet)
+
E_ISO_CREATION_FAILED=64
if [ "$quiet" ]; then
+
E_NULL_ISODIM=65
quiet="yes"
+
E_NO_WRITE_PERM=70
else
+
E_TESTING=71
quiet="no"
+
E_PREMATURE_INTERRUPTION=72
  +
E_NO_BACKFILE=80
  +
E_NO_CONFFILE=81
  +
E_BAD_OPTION=90
  +
E_BAD_PATH=91
  +
E_BAD_OPTDIM=92
  +
E_BAD_ISODIM=93
  +
E_BAD_REFTIME=94
  +
E_SHORT_REFTIME=95
  +
E_LITTLE_BACKDIR=96
  +
E_NO_FULL_ISODIR=100
  +
E_NO_ZIPPED_FILE=101
  +
E_BIG_ISODIM=102
  +
# }
  +
  +
# flags
  +
# {
  +
QUIET_FLAG=0 # modalità silente
  +
TEST_FLAG=0 # modalità di prova
  +
RESUME_FLAG=0 # modalità resume
  +
BACKFILE_FLAG=0 # modalità backup da file
  +
EXCLUDE_FLAG=1 # controllo exclude
  +
ZIP_FLAG=0 # modalità backup compresso
  +
INCREMENTAL_FLAG=0 # modalità backup incrementale
  +
OPTIMIZE_FLAG=0 # modalità backup ottimizzato
  +
  +
# }
  +
  +
# directory
  +
# {
  +
TMP=~/tmp # directory temporanea
  +
TEMPDIR=$(tempname) # directory temporanea per il backup
  +
IMGDIR=~/backup # directory delle immagini ISO
  +
# }
  +
  +
# file
  +
# {
  +
FILETEMP=$(tempname) # file temporaneo
  +
CONFILE=config # file di resume
  +
LIMENFILE=limen # file di confronto incrementale
  +
# }
  +
  +
# default values
  +
# {
  +
MAXDIM=4480
  +
ISODIM=$MAXDIM
  +
OPTDIM=1024
  +
BACKDIR=~
  +
EXCPATH=""
  +
# }
  +
  +
# controllo gli argomenti passatimi con getopts
  +
while getopts "hcI:O:M:p:e:n:qtf:r:i:s:l:zo" OPT; do
  +
case $OPT in
  +
h) dohelp;;
  +
c) doconf;;
  +
I) ISODIM="$OPTARG";;
  +
O) OPTDIM="$OPTARG";;
  +
M) MAXDIM="$OPTARG";;
  +
p) BACKDIR="$OPTARG";;
  +
e) EXCPATH="$OPTARG";;
  +
n) N="$OPTARG";;
  +
q) QUIET_FLAG=1;;
  +
t) TEST_FLAG=1;;
  +
r) RESUME_FLAG=1
  +
TEMPDIR="$OPTARG"
  +
BACKFILE="$TEMPDIR/$CONFILE";;
  +
f) BACKFILE_FLAG=1
  +
BACKFILE="$OPTARG";;
  +
i) INCREMENTAL_FLAG=1
  +
REFTIME="$OPTARG";;
  +
s) SORTING_METHOD="$OPTARG";;
  +
l) LABEL="$OPTARG";;
  +
z) ZIP_FLAG=1;;
  +
o) OPTIMIZE_FLAG=1;;
  +
*) echo "Spiacente, ma la funzione \"$OPT\" non esiste."
  +
echo "Prova a digitare \"$(basename $0) -h\" per ottenere aiuto."
  +
exit $E_BAD_OPTION;;
  +
esac
  +
done
  +
  +
# adesso arriva la parte complicata! devo decidere cosa fare in base alle opzioni
  +
# fornitemi. Possono presentarsi quattro casi:
  +
# 1- l'utente mi ha dato tutte le varibili necessarie con le opzioni -IOMpe
  +
# 2- l'utente mi ha detto di fare un resume con le opzioni -rn
  +
# 3- l'utente mi ha detto di fare un backup col file di configurazione -f
  +
# 4- l'utente non mi ha detto un tubo
  +
# è ovvio che prima che sia chiamata la funzione se_corretta_sintassi () devono
  +
# essere dichiarate tutte le altre variabili. Nel caso 4 valgono le impostazioni
  +
# di default prima assegnate
  +
if [ "$BACKFILE_FLAG" -eq "1" ]; then # caso 3
  +
preleva_conf newone
  +
elif [ "$RESUME_FLAG" -eq "1" ]; then # caso 2
  +
preleva_conf resume
fi
fi
case $funzione in
 
-h | --help) dohelp;;
 
-c | --conf) doconf;;
 
-f | --file) preleva_conf;;
 
-s | --save) preleva_dati $2 $3 $4 $5 $6;;
 
-r | --resume) preleva_resume $2 $3;;
 
*) echo "Spiacente, ma la funzione \"$funzione\" non esiste."
 
echo "Prova a digitare \"$(basename $0) --help\" per ottenere aiuto."
 
exit 1;;
 
esac
 
# inizializzo le altre variabili: se si è in resume, la variabile $tempdir
+
# inizializzo le altre variabili: se si è in resume, la variabile $TEMPDIR
# e la variabile $n sono state riassegnate
+
# e la variabile $N sono state riassegnate
okdir=$tempdir/okdir # elenco $okdir
+
OKDIR=$TEMPDIR/okdir # elenco $okdir
kodir=$tempdir/kodir # elenco $kodir
+
KODIR=$TEMPDIR/kodir # elenco $kodir
sparefiles=$tempdir/spare # elenco $sparefiles
+
SPAREFILES=$TEMPDIR/spare # elenco $sparefiles
isodir=$tempdir/isodir # directory immagine
+
ISODIR=$TEMPDIR/isodir # directory immagine
#inizializzo i file e le directory necessarie
#inizializzo i file e le directory necessarie
if [ ! -e $tempdir ]; then
+
if [ ! -e $TEMPDIR ]; then
mkdir -p $tempdir
+
mkdir -p $TEMPDIR
mkdir -p $isodir
+
mkdir -p $ISODIR
mkdir -p $imgdir
+
fi
  +
  +
if [ ! -e $IMGDIR ]; then
  +
mkdir -p $IMGDIR
fi
fi
# verifico che la creazione sia andata a buon fine
# verifico che la creazione sia andata a buon fine
if [ ! -e $tempdir -o ! -e $isodir -o ! -e $imgdir ]; then
+
if [ ! -e $TEMPDIR -o ! -e $ISODIR -o ! -e $IMGDIR ]; then
echo "Per qualche motivo non ho potuto creare le directory
echo "Per qualche motivo non ho potuto creare le directory
necessarie, quindi termino qui il compito, per evitare di far danno!
necessarie, quindi termino qui il compito, per evitare di far danno!
Spiacente!!!
+
Controlla di avere accesso in scrittura alla directory $TEMPDIR
"
"
exit 1
+
exit $E_NO_WRITE_PERM
fi
fi
# controllo che i dati inseriti siano coerenti
# controllo che i dati inseriti siano coerenti
se_corretta_sintassi
+
if ! corretta_sintassi; then
  +
exit $?
  +
fi
# calcolo la dimensione totale della directory $backdir e il numero approssimativo
+
# se i controlli precedenti sono andati a buon fine, creo il file $LIMENFILE nella
  +
# directory $TEMPDIR
  +
touch -t $REFTIME $TEMPDIR/$LIMENFILE
  +
  +
# calcolo la dimensione totale della directory $BACKDIR e il numero approssimativo
# di supporti da utilizzare
# di supporti da utilizzare
totdim=$(du -k --max-depth 0 $backdir | cut -f1)
+
echo -n "Attendere, calcolo dello spazio utilizzato in corso..."
let "ndvd=($totdim/1024)/($maxdim)+1"
+
# se la variabile $EXCPATH è vuota, imposto $EXCDIM a zero
  +
if [ $EXCPATH ]; then
  +
EXCDIM=$(du -m -s -c $(echo $EXCPATH | xargs -d ,) | tail -n 1 | cut -f1)
  +
else
  +
EXCDIM=0
  +
fi
  +
TOTDIM=$(du -m --max-depth 0 $BACKDIR | cut -f1)
  +
let "NDVD=($TOTDIM-$EXCDIM)/($MAXDIM)+1"
  +
echo "terminato!"
  +
echo ""
# stampo a video la configurazione attuale
# stampo a video la configurazione attuale
echo "*************************************************************************"
+
cat <<end-of-actual-configuration
echo "Sarà effettuato il backup completo della directory $backdir"
+
=========================================================================
echo "La dimensione dell'immagine ISO è impostata a $isodim MB"
+
$(basename $0) v3.0 - configurazione di backup
echo "La dimensione ottimale è impostata a $optdim MB"
+
=========================================================================
echo "La dimensione dei supporti è impostata a $maxdim MB"
+
> Sarà effettuato il backup completo della directory: $BACKDIR
echo "*************************************************************************"
+
> La dimensione dell'immagine ISO è impostata a: $ISODIM MB
echo "Saranno necessari approssimativamente $ndvd supporti"
+
> La dimensione ottimale è impostata a: $OPTDIM MB
echo "*************************************************************************"
+
> La dimensione dei supporti è impostata a: $MAXDIM MB
echo ""
+
> Saranno necessari approssimativamente: $NDVD dischi
echo ""
+
=========================================================================
  +
end-of-actual-configuration
# riporto i MB in KB
# riporto i MB in KB
let "optdim=$optdim*1024"
+
let "OPTDIM=$OPTDIM*1024"
let "isodim=$isodim*1024"
+
let "ISODIM=$ISODIM*1024"
let "maxdim=$maxdim*1024"
+
let "MAXDIM=$MAXDIM*1024"
  +
let "TOTDIM=$TOTDIM*1024"
  +
  +
# imposto le opzioni corrette di sort in base al tipo di ordinamento scelto
  +
if [ "$SORTING_METHOD" == "inum" ]; then
  +
SORT_OPTS="-nr"
  +
elif [ "$SORTING_METHOD" == "num" ]; then
  +
SORT_OPTS="-n"
  +
elif [ "$SORTING_METHOD" == "alph" ]; then
  +
SORT_OPTS="-d -k 3"
  +
else
  +
SORT_OPTS="-nr"
  +
fi
# creo la lista dei file e delle directory, a meno che non tratti di un resume
# creo la lista dei file e delle directory, a meno che non tratti di un resume
# per cui copio i file di backup nelle liste per evitare di tralasciare alcuni
# per cui copio i file di backup nelle liste per evitare di tralasciare alcuni
# file
# file
if [ "$work" != "resume" ]; then
+
if [ "$RESUME_FLAG" -eq "0" ]; then
echo -n "Sto creando la lista delle directory e dei file..."
echo -n "Sto creando la lista delle directory e dei file..."
crea_lista
+
if ! crea_lista; then
  +
exit $?
  +
fi
echo "terminato!"
echo "terminato!"
elif [ "$work" = "resume" ]; then
+
elif [ "$RESUME_FLAG" -eq "1" ]; then
cp -f $tempdir/backup_$(basename $okdir)~ $okdir
+
cp -f $TEMPDIR/backup_$(basename $OKDIR)~ $OKDIR
cp -f $tempdir/backup_$(basename $sparefiles)~ $sparefiles
+
cp -f $TEMPDIR/backup_$(basename $SPAREFILES)~ $SPAREFILES
  +
fi
  +
  +
# se è stata data l'opzione di test, allora mi fermo qui
  +
if [ "$TEST_FLAG" -eq "1" ]; then
  +
echo ""
  +
echo "È stata data l'opzione di test, dunque non proseguirò oltre!"
  +
exit $E_TESTING
fi
fi
Riga 418: Riga 431:
echo "Procedo alla creazione delle immagini ISO..."
echo "Procedo alla creazione delle immagini ISO..."
echo "Per visualizzare i progressi, entra in una shell e dai il comando"
echo "Per visualizzare i progressi, entra in una shell e dai il comando"
echo "tail -f "$tempdir"/tar_output"
+
echo "tail -f "$TEMPDIR"/tar_output"
while [ -s $okdir -o -s $sparefiles ]; do
+
while [ -s $OKDIR -o -s $SPAREFILES ]; do
isoname="backup_$(date -d "today" +%Y%m%d)_$n.iso"
+
# creo la label e il nome dell'immagine ISO di backup,
echo -e "\tCreo l'immagine $isoname..."
+
# nel caso non siano stati già assegnati
while se_pieno; do
+
if [ ! $LABEL ]; then
if se_entra $okdir; then
+
ISOLABEL="backup_$(date -d "today" +%Y%m%d)_$N"
echo -en "\t\tSto comprimendo la directory"
+
ISONAME="$ISOLABEL".iso
comprimi $okdir
+
else
# let "i=$i+1"
+
ISOLABEL=$LABEL$N
k=0
+
ISONAME="$ISOLABEL".iso
  +
fi
  +
echo ""
  +
echo -e "\tCreo l'immagine $ISONAME..."
  +
while ! pieno; do
  +
if entra $OKDIR; then
  +
echo -en "\t\tSto salvando la directory"
  +
immagazzina $OKDIR
  +
K=0
echo " terminato!"
echo " terminato!"
elif se_entra $sparefiles; then
+
elif entra $SPAREFILES; then
echo -en "\t\tSto comprimendo il file"
+
echo -en "\t\tSto salvando il file"
comprimi $sparefiles
+
immagazzina $SPAREFILES
# let "i=$i+1"
+
K=0
k=0
 
echo " terminato!"
echo " terminato!"
fi
fi
if [ ! -s $okdir -a ! -s $sparefiles ]; then
+
if [ ! -s $OKDIR -a ! -s $SPAREFILES ]; then
break
break
fi
fi
let "k++"
+
let "K++"
done
done
echo "Sto creando l'immagine ISO $isoname..."
+
echo "Sto creando l'immagine ISO $ISONAME..."
echo "Per visualizzare i progressi, entra in una shell e dai il comando"
echo "Per visualizzare i progressi, entra in una shell e dai il comando"
echo "tail -f "$tempdir"/"$isoname"_output"
+
echo "tail -f "$TEMPDIR"/"$ISONAME"_output"
crea_iso
crea_iso
let "n++"
+
let "N++"
rm -f $isodir/*
+
rm -Rf $ISODIR/*
# i=0
# i=0
echo -e "\tterminato!"
echo -e "\tterminato!"
echo "--> E' stata creata l'immagine ISO $isoname nella directory $imgdir,"
+
echo "--> E' stata creata l'immagine ISO $ISONAME nella directory $IMGDIR,"
echo "--> per cui si prega di procedere alla masterizzazione prima di proseguire."
echo "--> per cui si prega di procedere alla masterizzazione prima di proseguire."
echo "--> Io restero' in attesa che tu mi dica \"prosegui\"."
echo "--> Io restero' in attesa che tu mi dica \"prosegui\"."
while true; do
while true; do
if [[ $quiet = "no" ]]; then
+
if [ "$QUIET_FLAG" -eq "0" ]; then
read scelta
+
read SCELTA
if [ "$scelta" = "prosegui" ]; then
+
if [ "$SCELTA" = "prosegui" ]; then
break
break
elif [ "$scelta" = "termina" ]; then
+
elif [ "$SCELTA" = "termina" ]; then
echo "Rinominerò la cartella \"$tempdir\" in \"backup_$(date -d "today" +%Y%m%d)\""
+
echo "Rinominerò la cartella \"$TEMPDIR\" in \"backup_$(date -d "today" +%Y%m%d)\""
echo "così che tu possa riconoscerla facilmente"
echo "così che tu possa riconoscerla facilmente"
mv $tempdir $(dirname "$tempdir")/backup_$(date -d "today" +%Y%m%d)
+
mv $TEMPDIR $(dirname "$TEMPDIR")/backup_$(date -d "today" +%Y%m%d)
exit 0
+
exit $E_PREMATURE_INTERRUPTION
else
else
echo "Scegli \"prosegui\" per continuare nella procedura di backup"
echo "Scegli \"prosegui\" per continuare nella procedura di backup"
Riga 467: Riga 480:
echo "Puoi sempre riprendere più tardi con \"$(basename $0) --resume\""
echo "Puoi sempre riprendere più tardi con \"$(basename $0) --resume\""
fi
fi
elif [[ $quiet = "yes" ]]; then
+
elif [ "$QUIET_FLAG" -eq "1" ]; then
break
break
fi
fi
done
done
scelta=""
+
SCELTA=""
done
done
Riga 481: Riga 494:
# =======================================================================================
# =======================================================================================
</pre>
</pre>
* Data: 21/10/2007
+
* Data: 25/03/2009
* Autore: Tiferet
* Autore: Tiferet

Versione delle 12:09, 25 mar 2009

Descrizione

Questo script ha lo scopo di organizzare un backup completo di un path liberamente definibile. Lo script organizza i dati in immagini iso di grandezza definibile e le masterizza man mano.

Download

http://www.slacky.eu/misto/concorso/tiferet/backntar

Script

#!/bin/bash
# The bash/sh interpreter
# =======================================================================================
# questo script ha lo scopo di organizzare un backup completo di
# un path liberamente definibile. Lo script organizza i dati in
# immagini iso di grandezza definibile e le masterizza man mano.
# =======================================================================================

# =======================================================================================
# inizio dichiarazione delle funzioni
# =======================================================================================

function dohelp ()
{
# se mi chiedi aiuto o non sai come usarmi, ti spiego

cat <<end-of-help
$(basename $0) v3.0
Questo script ha lo scopo di organizzare un backup completo di un path liberamente
definibile.  Lo script organizza i dati in immagini iso di grandezza data.

Utilizzo:
$(basename $0) [opzioni]

OPZIONI:
-h:		stampa questo help ed esce;
-c:		mostra la configurazione contenuta all'interno del file di configurazione;
-M dim:	imposta a "dim" MB la dimensione massima dell'immagine ISO;
-I dim:	imposta a "dim" MB la dimensione preferita dell'immagine ISO, per default pari
		alla dimensione massima;
-O dim:	imposta a "dim" MB la dimensione ottimale delle directory;
-p path:	effettua il backup della directory "path";
-e list:	esclude dal backup le directory contenute in "list";
-n num:	l'indice progressivo di backup parte da "num";
-q:		modalità quiet, le immagini ISO sono create senza soluzione di continuità;
-t:		modalità test, crea la lista di backup ed esce;
-r path:	effettua il resume dell'ultimo backup effettuato, essendo "path" la directory
		creata nello scorso backup;
-f file:	effettua il backup con le impostazioni contenute all'interno
		del file "file";
-i date:	modalità incrementale, backup di tutti i file più recenti di "date";
-s opt:	opzioni di ordinamento:
			> alph, ordinamento alfabetico
			> num, ordinamento numerico
			> inum, ordinamento numerico inverso (default)
-l name:	imposta a "name" il nome dell'immagine ISO, aggiungendo un numero progressivo
-z:		modalità compressa, ogni directory e file è compresso in un archivio tar.bz2
-o:		modalità ottimizzata, ogni immagine ISO è riempita fino alla sua massima
		capienza, stipando file via via più piccoli

AVVERTENZE:
-->	Le dimensioni fornite devono essere tali che optdim << isodim < maxdim
-->	È possibile che una directory da escludere, se posta all'interno di una directory
	di dimensione minore di optdim MB, sia comunque inclusa
-->	Non sono inclusi nel set di backup i link simbolici
-->	È sempre consigliabile verificare, mediante l'opzione -t, cosa lo script andrà
	effettivamente a salvare

Se avete suggerimenti o avete trovato un bug, vi prego di comunicarmelo.
tiferet dot angelo at tiscali dot it
end-of-help
exit 0
}

function doconf ()
{
# se mi chiedi la configurazione attuale, te la do senza discutere

# controllo se il file di configurazione esiste
if [ "$BACKFILE_FLAG" -eq "1" ]; then
	preleva_conf newone
elif [ "$RESUME_FLAG" -eq "1" ]; then
	preleva_conf resume
else
	BACKFILE="no file, default configuration"
fi

# stampo la configurazione
cat <<end-of-configuration
=========================================================================
$(basename $0) v3.0 - configurazione contenuta nel file:
--> $BACKFILE
=========================================================================
> Sarà effettuato il backup completo della directory:	$BACKDIR
> La dimensione dell'immagine ISO è impostata a:	$ISODIM	MB
> La dimensione ottimale è impostata a:			$OPTDIM	MB
> La dimensione dei supporti è impostata a:		$MAXDIM	MB
========================================================================="
end-of-configuration
exit 0
}

function tempname ()
{
# la funzione tempname serve per restituire in uscita un nome casuale
STRING=$(mcookie)
NAME=${STRING:0:LEN}
NAME_TEMP=$TMP/$NAME.temp

while [ -e $NAME_TEMP ]; do
	STRING=$(mcookie)
	NAME=${STRING:0:LEN}
	NAME_TEMP=$NAME.temp
done

echo $NAME_TEMP
}

function preleva_conf ()
{
# la funzione preleva_conf serve per verificare, ove necessario, l'esistenza del
# file di configurazione e quindi di prelevare i valori corretti delle impostazioni
# il comportamento della funzione cambia a seconda che le sia stato passato il comando
# "newone" ovvero "resume"
if [ ! -e $BACKFILE -a "$1" == "newone" ]; then
	echo "Non esiste ancora un file di configurazione!"
	echo "Ne creerò uno di default, ma è opportuno controllarlo!"
(
cat <<end-of-default-conf-file
backup_path		:{please, insert path for directory to backup}:
iso_dimension	:$ISODIM:
opt_dimension	:$OPTDIM:
max_dimension	:$MAXDIM:
exclude_path	:foo1,foo2,foo3:
end-of-default-conf-file
) > $BACKFILE
	exit $E_NO_BACKFILE
elif [ ! -e $BACKFILE -a "$1" == "resume" ]; then
	echo "Spiacente, ma non è possibile effettuare il resume!"
	echo "Non è stato possibile trovare il file di resume:"
	echo "\"$BACKFILE\""
	echo "Controlla che esista e che sia leggibile"
	exit $E_NO_CONFFILE
else
	BACKDIR=$(grep 'backup_path' $BACKFILE | cut "-d:" -f2)
	ISODIM=$(grep 'iso_dimension' $BACKFILE | cut "-d:" -f2)
	OPTDIM=$(grep 'opt_dimension' $BACKFILE | cut "-d:" -f2)
	MAXDIM=$(grep 'max_dimension' $BACKFILE | cut "-d:" -f2)
	EXCPATH=$(grep 'exclude_path' $BACKFILE | cut "-d:" -f2)
	LINE=$(grep 'line' $BACKFILE | cut "-d:" -f2)
	return 0
fi
}

function corretta_sintassi ()
{
#  la funzione se_corretta_sintassi verifica che sia stato dato il corretto numero e
# formato di dati del backup.

# path inesistente?
if [ ! -e $BACKDIR ]; then
	echo "Penso che tu abbia sbagliato ad indicarmi il percorso..."
	return $E_BAD_PATH
# ordine sbagliato?
elif [ $OPTDIM -gt $ISODIM ]; then
	echo "La dimensione ottimale ($OPTDIM MB) non può essere superiore"
	echo "alla dimensione dell'immagine ISO ($ISODIM MB)."
	return $E_BAD_OPTDIM
elif [ $ISODIM -gt $MAXDIM ]; then
	echo "La dimensione dell'immagine ISO ($ISODIM MB) non può essere superiore"
	echo "alla dimensione del supporto ($MAXDIM MB)."
	return $E_BAD_ISODIM
fi

# creo il file config contenente le informazioni sul backup, per un eventuale resume
if [ "$RESUME_FLAG" -eq "0" ]; then
(
cat <<end-of-resume-file
backup_path		:$BACKDIR:
iso_dimension	:$ISODIM:
opt_dimension	:$OPTDIM:
max_dimension	:$MAXDIM:
exclude_path	:$EXCPATH:
end-of-resume-file
) > $TEMPDIR/$CONFILE
fi

# controllo la validità del $REFTIME, se dato, ed in caso lo imposto ad una data arcaica
# in modo da attivare il backup totale [yyyymmddHHMM]
if [ "$INCREMENTAL_FLAG" -eq "0" ]; then
	REFTIME=197001010000
fi

# controllo che $REFTIME sia effettivamente un numero almeno positivo....
if [ "$REFTIME" -lt "0" ]; then
	echo "Spiacente, ma credo che ci sia qualche problema con la data di riferimento"
	echo "--> $REFTIME"
	return $E_BAD_REFTIME
fi

# controllo che $REFTIME abbia le informazioni necessarie
REFTIME_CHARS=$(echo -n $REFTIME | wc -m)
if [ "$REFTIME_CHARS" -ne "12" ]; then
	echo "Spiacente, ma devi indicare anno, mese, giorno, ore e minuti"
	echo "della data di riferimento (yyyymmddHHMM)"
	return $E_SHORT_REFTIME
fi
}

function crea_lista ()
{
# la funzione crea_lista serve ad ottenere i file $okdir e $sparefile che contengono
# l'elenco delle directory aventi dimensioni inferiori a $optdim e l'elenco dei file
# rimanenti.

# controllo che la directory $backdir non entri in un singolo supporto; in quel caso non
# c'é bisogno di fare alcunché, altrimenti creo la lista delle sottodirectory, eliminando
# la prima riga che contiene proprio la $BACKDIR
if [ "$TOTDIM" -gt "$MAXDIM" ]; then
	du -k --time --time-style=+%Y%m%d%H%M --max-depth 1 $BACKDIR | \
	head -n -1  | sort $SORT_OPTS -o $KODIR
	find "$BACKDIR" -maxdepth 1 -type f -newer $TEMPDIR/$LIMENFILE \
	-printf "%k\t%CY%Cm%Cd%CH%CM\t%p\n" >> $SPAREFILES
else
	echo "errore!"
	echo "La directory $BACKDIR ha un dimensione inferiore a quella di un singolo"
	echo "supporto: $TOTDIM KB < $MAXDIM KB. Pertanto non è necessario proseguire"
	exit $E_LITTLE_BACKDIR
fi

# controllo che all'interno di $BACKDIR non vi siano file di dimensione maggiore
# $MAXDIM, che non sarebbero mai salvati
HUGEFILE=$(find $BACKDIR -type f -size +"$MAXDIM"k)
if [ "$HUGEFILE" ]; then
	echo "Spiacente, ma i seguenti file:"
	echo $HUGEFILE
	echo "hanno una dimensione maggiore di $MAXDIM KB, pertanto non possono"
	echo "essere salvati. Eliminali o suddividili in altri più piccoli, poi"
	echo "riprendi l'operazione di backup."
	return $E_HUGEFILE
fi

# se la directory da backuppare non entra in un singolo supporto,
# allora è meglio scomporla in più sotto-directory.
while [ -s $KODIR ]; do
	EXCLUDE_FLAG=1
	read FIRST_LINE < $KODIR
	DIRDIM=$(echo $FIRST_LINE | cut "-d " -f1)
	DIRTIME=$(echo $FIRST_LINE | cut "-d " -f2)
	DIRNAME=$(echo $FIRST_LINE | cut "-d " -f3-)
# se la directory in esame è nell'insieme dei path da escludere o non è stata modificata
# prima del $REFTIME, la elimino e passo alla successiva. Similmente, il comando find
# trova soltanto i file più recenti del $LIMENFILE creato precedentemente con il comando
# touch e il timestamp indicato per default o dall'utente
	while [ $EXCLUDE_FLAG -eq 1 ]; do
		EXCLUDE_FLAG=0
		for EXCLUDE in `echo $EXCPATH | xargs -d ,`; do
			if [ "$EXCLUDE" == "$DIRNAME" -o "$DIRTIME" -lt "$REFTIME" ]; then
				sed 1d $KODIR | sort $SORT_OPTS -o $KODIR
# 				il controllo seguente è necessario per controllare che l'ultima
# 				riga eliminata non abbia svuotato il file $KODIR, cosa che
# 				non permetterebbe l'assegnazione delle variabili $DIRNAME,
# 				$DIRTIME e $DIRDIM
				if [ -s $KODIR ]; then
					read FIRST_LINE < $KODIR
					DIRDIM=$(echo $FIRST_LINE | cut "-d " -f1)
					DIRTIME=$(echo $FIRST_LINE | cut "-d " -f2)
					DIRNAME=$(echo $FIRST_LINE | cut "-d " -f3-)
					EXCLUDE_FLAG=1
				else
					DIRDIM=0
					DIRTIME=0
					DIRNAME=""
					EXCLUDE_FLAG=0
					break
				fi
			fi
		done
	done
# 	verificare che l'ultima voce del file $KODIR sia effettivamente messa in $OKDIR
	if [ -n "$DIRNAME" ]; then
		if [ "$DIRDIM" -gt "$OPTDIM" ]; then
			du -k --time --time-style=+%Y%m%d%H%M --max-depth 1 "$DIRNAME" | \
			head -n -1 >> $KODIR
			find "$DIRNAME" -maxdepth 1 -type f -newer $TEMPDIR/$LIMENFILE \
			-printf "%k\t%CY%Cm%Cd%CH%CM\t%p\n" >> $SPAREFILES
			sed 1d $KODIR | sort $SORT_OPTS -o $KODIR
		else
			echo -e "$DIRDIM\t$DIRTIME\t$DIRNAME" >> $OKDIR
			sed 1d $KODIR | sort $SORT_OPTS -o $KODIR
		fi
	fi
done

# creo una copia di backup delle due liste, sempre che non siano file vuoti
if [ -s $OKDIR ]; then
	cp $OKDIR $TEMPDIR/backup_$(basename $OKDIR)~
	cat $OKDIR | sort $SORT_OPTS -o $OKDIR
else
	echo "" > $TEMPDIR/backup_$(basename $OKDIR)~
fi

if [ -s $SPAREFILES ]; then
	cp $SPAREFILES $TEMPDIR/backup_$(basename $SPAREFILES)~
	cat $SPAREFILES | sort $SORT_OPTS -o $SPAREFILES
else
	echo "" > $TEMPDIR/backup_$(basename $SPAREFILES)~
fi

# conto di quante linee siano composti i due elenchi e sommo i risultati. Il totale
# costituisce il numero massimo di iterazioni che si può compiere per creare una
# singola immagine ISO, quindi scrivo il risultato nel file $confile
if [ -s $OKDIR ]; then
	local DIRLINES=$(wc -l $OKDIR | cut "-d " -f1)
else
	local DIRLINES=0
fi

if [ -s $SPAREFILES ]; then
	local FILELINES=$(wc -l $SPAREFILES | cut "-d " -f1)
else
	local FILELINES=0
fi
let "LINE=$DIRLINES+$FILELINES"
echo "line		:$LINE:" >> $TEMPDIR/$CONFILE

return 0
}

function entra ()
{
# la funzione se_entra ha il compito di verificare che il primo elemento dell'elenco
#  trasmessogli come argomento abbia dimensioni tali da entrare nella directory $isodir

# prendo la lista che mi viene passata
local LIST="$1"

# leggo la prima riga, ossia la directory (o file) più grande
if [ -s $LIST ]; then
	local FIRST_LINE
	read FIRST_LINE < $LIST
else
	return 1
fi
DIRDIM=$(echo $FIRST_LINE | cut "-d " -f1)

# verifico lo spazio disponibile e dunque se la directory (o file) può entrare
local BUSYDIM=$(du -k --max-depth 0 $ISODIR | cut -f1)
local FREEDIM
let "FREEDIM=$MAXDIM-$BUSYDIM"
if [ "$DIRDIM" -le "$FREEDIM" ]; then
	return 0
elif [ "$OPTIMIZE_FLAG" -eq "1" ]; then
	sed 1d $LIST > $FILETEMP
	mv -f $FILETEMP $LIST
	echo $FIRST_LINE >> $LIST
	return 1
else
	return 1
fi
}

function immagazzina ()
{
# la funzione "comprimi" ha la funzione di comprimere in un archivio .tar.bz2 la directory
# contenuta nella prima riga della lista delle directory da backuppare. Tale lista deve
# essere passata come primo argomento.

# prendo la lista che mi viene passata
local LIST="$1"

# leggo la prima riga, ossia la directory (o file) più grande
local FIRST_LINE
read FIRST_LINE < $LIST
local DIRPATH=$(echo $FIRST_LINE | cut "-d " -f3-)

# procedo al salvataggio, differente a seconda che io debba comprimere oppure no
if [ "$ZIP_FLAG" -eq "1" ]; then
# 	creo il nome dell'archivio compresso, se necessario
	ARCHNAME="$(echo $DIRPATH | sed s:$BACKDIR/:backup:g | sed s:/:_:g | sed s:" ":_:g)"
# 	comprimo la directory più grande
	echo -n " $(basename "$DIRPATH"), "
	if ! compresso "$(basename "$DIRPATH")"; then
		echo -n "comprimo..."
		tar -cvjf $ISODIR/$ARCHNAME.tar.bz2 "$DIRPATH" >> $TEMPDIR/tar_output 2>&1
	else
		echo -n "già compresso..."
		tar -cvf $ISODIR/$ARCHNAME.tar "$DIRPATH" >> $TEMPDIR/tar_output 2>&1
	fi
elif [ "$ZIP_FLAG" -eq "0" ]; then
# 	prendo l'albero delle directory sotto cui sta la directory o il file in esame e lo
# 	ricreo in $ISODIR, a meno che non esiste già e.g. nel caso di sottodirectory o nel
# 	caso in cui stia tentando di creare la cartella .
	echo -n " $(basename "$DIRPATH")..."
	DIRTREE=$(dirname "$DIRPATH")
	if [ ! -e $ISODIR/$DIRTREE ]; then
		mkdir -p "$ISODIR/$DIRTREE"
	fi
# 	quindi copio la directory o il file in esame in $ISODIR/$DIRTREE
	cp -a "$DIRPATH" "$ISODIR/$DIRTREE"
fi

# cancello la prima riga dalla lista
sed 1d $LIST > $FILETEMP
mv -f $FILETEMP $LIST

return 0
}

function compresso ()
{
# la funzione se_compresso verifica se l'argomento passato è già stato compresso e
# restituisce 1 o 0 a seconda che sia stato o no compresso.

local FILE="$1"

# con egrep verifico se nel nome del file sia contenuta un'estensione tipica dei
# formati compressi
local ZIP=$(echo $FILE | egrep .'\<tar\>|\<rar\>|\<zip\>|\<gz\>|\<bz2\>|\<tgz\>|\<iso\>')

# restituisco il valore opportuno
if [ "$ZIP" ]; then
	return 0
else
	return $E_NO_ZIPPED_FILE
fi

}

function pieno ()
{
# la funzione se_pieno verifica che la cartella $isodir non abbia raggiunto la dimensione
# limite stabilita per la masterizzazione e restituisce 1 o 0 a seconda che si sia
# raggiunto o no tale limite

local BUSYDIM=$(du -k --max-depth 0 $ISODIR | cut -f1)

if [ "$BUSYDIM" -ge "$ISODIM" -o "$K" -ge "$LINE" ]; then
	K=0
	return 0
else
	return $E_NO_FULL_ISODIR
fi

}

function crea_iso ()
{
# la funzione crea_iso non fa altro che convertire in un'immagine iso la directory
# $isodir e successivamente attende verifica che la dimensione finale sia inferiore al
# limite di capienza del supporto
mkisofs -r -V $ISOLABEL -o $IMGDIR/$ISONAME $ISODIR >> $TEMPDIR/"$ISONAME"_output 2>&1

# prima di proseguire, controllo che l'immagine esista e che abbia dimensione non nulla
if [ -e $IMGDIR/$ISONAME -a -s $IMGDIR/$ISONAME ]; then
	local IMGDIM=$(du -k $IMGDIR/$ISONAME | cut -f1)
elif [ ! -e $IMGDIR/$ISONAME ]; then
	echo "=========================================================================="
	echo "Per qualche strano motivo, l'immagine non è stata creata."
	echo ""
	echo "Mi dispiace, ma il backup si interrompe qui; controlla cosa è andato"
	echo "storto e riprendi con \"$(basename $0) --resume\""
	echo "=========================================================================="
	exit $E_ISO_CREATION_FAILED
elif [ ! -s $IMGDIR/$ISONAME ]; then
	echo "=========================================================================="
	echo "Per qualche strano motivo,  l'immagine creata  ha dimensione nulla,"
	echo "probabilmente perché esiste un file singolo di dimensioni superiori"
	echo "a quelle del singolo supporto."
	echo ""
	echo "Mi dispiace, ma il backup si interrompe qui; controlla cosa è andato"
	echo "storto e riprendi con \"$(basename $0) --resume\""
	echo "=========================================================================="
	exit $E_NULL_ISODIM
fi

# riordino le liste dei file e delle directory e aggiorno le copie di backup delle liste
if [ -s $OKDIR ]; then
	cat $OKDIR | sort $SORT_OPTS -o $OKDIR
	cp -f $OKDIR $TEMPDIR/backup_$(basename $OKDIR)~
fi

if [ -s $SPAREFILES ]; then
	cat $SPAREFILES | sort $SORT_OPTS -o $SPAREFILES
	cp -f $SPAREFILES $TEMPDIR/backup_$(basename $SPAREFILES)~
fi

# per sicurezza, controllo che la dimensione effettiva dell'immagine sia inferiore al
# limite massimo
if [ "$IMGDIM" -le "$MAXDIM" ]; then
	return 0
else
	return $E_BIG_ISODIM
fi
}

# =======================================================================================
# fine dichiarazione delle funzioni
# =======================================================================================

# =======================================================================================
# inizio programma principale
# =======================================================================================

# inizializzo le variabili $n e $tempdir e quelle non dipendenti da queste due
# le altre devono essere inizializzate dopo che si è scelta la funzione da utilizzare

# indici
# {
	K=0					# indice riempimento
	M=0					# indice file multipli
	N=1					# indice nome backup
	LEN=6					# lunghezza stringa casuale
# }

# codici di errore
# {
	E_ISO_CREATION_FAILED=64
	E_NULL_ISODIM=65
	E_NO_WRITE_PERM=70
	E_TESTING=71
	E_PREMATURE_INTERRUPTION=72
	E_NO_BACKFILE=80
	E_NO_CONFFILE=81
	E_BAD_OPTION=90
	E_BAD_PATH=91
	E_BAD_OPTDIM=92
	E_BAD_ISODIM=93
	E_BAD_REFTIME=94
	E_SHORT_REFTIME=95
	E_LITTLE_BACKDIR=96
	E_NO_FULL_ISODIR=100
	E_NO_ZIPPED_FILE=101
	E_BIG_ISODIM=102
# }

# flags
# {
	QUIET_FLAG=0			# modalità silente
	TEST_FLAG=0				# modalità di prova
	RESUME_FLAG=0			# modalità resume
	BACKFILE_FLAG=0			# modalità backup da file
	EXCLUDE_FLAG=1			# controllo exclude
	ZIP_FLAG=0				# modalità backup compresso
	INCREMENTAL_FLAG=0		# modalità backup incrementale
	OPTIMIZE_FLAG=0			# modalità backup ottimizzato

# }

# directory
# {
	TMP=~/tmp				# directory temporanea
	TEMPDIR=$(tempname)		# directory temporanea per il backup
	IMGDIR=~/backup			# directory delle immagini ISO
# }

# file
# {
	FILETEMP=$(tempname)		# file temporaneo
	CONFILE=config			# file di resume
	LIMENFILE=limen			# file di confronto incrementale
# }

# default values
# {
	MAXDIM=4480
	ISODIM=$MAXDIM
	OPTDIM=1024
	BACKDIR=~
	EXCPATH=""
# }

# controllo gli argomenti passatimi con getopts
while getopts "hcI:O:M:p:e:n:qtf:r:i:s:l:zo" OPT; do
	case $OPT in
	h)	dohelp;;
	c)	doconf;;
	I)	ISODIM="$OPTARG";;
	O)	OPTDIM="$OPTARG";;
	M)	MAXDIM="$OPTARG";;
	p)	BACKDIR="$OPTARG";;
	e)	EXCPATH="$OPTARG";;
	n)	N="$OPTARG";;
	q)	QUIET_FLAG=1;;
	t)	TEST_FLAG=1;;
	r)	RESUME_FLAG=1
		TEMPDIR="$OPTARG"
		BACKFILE="$TEMPDIR/$CONFILE";;
	f)	BACKFILE_FLAG=1
		BACKFILE="$OPTARG";;
	i)	INCREMENTAL_FLAG=1
		REFTIME="$OPTARG";;
	s)	SORTING_METHOD="$OPTARG";;
	l)	LABEL="$OPTARG";;
	z)	ZIP_FLAG=1;;
	o)	OPTIMIZE_FLAG=1;;
	*)	echo "Spiacente, ma la funzione \"$OPT\" non esiste."
		echo "Prova a digitare \"$(basename $0) -h\" per ottenere aiuto."
		exit $E_BAD_OPTION;;
	esac
done

# adesso arriva la parte complicata! devo decidere cosa fare in base alle opzioni
# fornitemi. Possono presentarsi quattro casi:
# 1- l'utente mi ha dato tutte le varibili necessarie con le opzioni -IOMpe
# 2- l'utente mi ha detto di fare un resume con le opzioni -rn
# 3- l'utente mi ha detto di fare un backup col file di configurazione -f
# 4- l'utente non mi ha detto un tubo
# è ovvio che prima che sia chiamata la funzione se_corretta_sintassi () devono
# essere dichiarate tutte le altre variabili. Nel caso 4 valgono le impostazioni
# di default prima assegnate
if [ "$BACKFILE_FLAG" -eq "1" ]; then # caso 3
	preleva_conf newone
elif [ "$RESUME_FLAG" -eq "1" ]; then # caso 2
	preleva_conf resume
fi


# inizializzo le altre variabili: se si è in resume, la variabile $TEMPDIR
# e la variabile $N sono state riassegnate
OKDIR=$TEMPDIR/okdir			# elenco $okdir
KODIR=$TEMPDIR/kodir			# elenco $kodir
SPAREFILES=$TEMPDIR/spare		# elenco $sparefiles
ISODIR=$TEMPDIR/isodir			# directory immagine

#inizializzo i file e le directory necessarie
if [ ! -e $TEMPDIR ]; then
	mkdir -p $TEMPDIR
	mkdir -p $ISODIR
fi

if [ ! -e $IMGDIR ]; then
	mkdir -p $IMGDIR
fi

# verifico che la creazione sia andata a buon fine
if [ ! -e $TEMPDIR -o ! -e $ISODIR -o ! -e $IMGDIR ]; then
	echo "Per qualche motivo non ho potuto creare le directory
necessarie, quindi termino qui il compito, per evitare di far danno!
Controlla di avere accesso in scrittura alla directory $TEMPDIR
"
	exit $E_NO_WRITE_PERM
fi

# controllo che i dati inseriti siano coerenti
if ! corretta_sintassi; then
	exit $?
fi

# se i controlli precedenti sono andati a buon fine, creo il file $LIMENFILE nella
# directory $TEMPDIR
touch -t $REFTIME $TEMPDIR/$LIMENFILE

# calcolo la dimensione totale della directory $BACKDIR e il numero approssimativo
# di supporti da utilizzare
echo -n "Attendere, calcolo dello spazio utilizzato in corso..."
# se la variabile $EXCPATH è vuota, imposto $EXCDIM  a zero
if [ $EXCPATH ]; then
	EXCDIM=$(du -m -s -c $(echo $EXCPATH | xargs -d ,) | tail -n 1  | cut -f1)
else
	EXCDIM=0
fi
TOTDIM=$(du -m --max-depth 0 $BACKDIR | cut -f1)
let "NDVD=($TOTDIM-$EXCDIM)/($MAXDIM)+1"
echo "terminato!"
echo ""

# stampo a video la configurazione attuale
cat <<end-of-actual-configuration
=========================================================================
$(basename $0) v3.0 - configurazione di backup
=========================================================================
> Sarà effettuato il backup completo della directory:	$BACKDIR
> La dimensione dell'immagine ISO è impostata a:	$ISODIM	MB
> La dimensione ottimale è impostata a:			$OPTDIM	MB
> La dimensione dei supporti è impostata a:		$MAXDIM	MB
> Saranno necessari approssimativamente:		$NDVD	dischi
=========================================================================
end-of-actual-configuration

# riporto i MB in KB
let "OPTDIM=$OPTDIM*1024"
let "ISODIM=$ISODIM*1024"
let "MAXDIM=$MAXDIM*1024"
let "TOTDIM=$TOTDIM*1024"

# imposto le opzioni corrette di sort in base al tipo di ordinamento scelto
if [ "$SORTING_METHOD" == "inum" ]; then
	SORT_OPTS="-nr"
elif [ "$SORTING_METHOD" == "num" ]; then
	SORT_OPTS="-n"
elif [ "$SORTING_METHOD" == "alph" ]; then
	SORT_OPTS="-d -k 3"
else
	SORT_OPTS="-nr"
fi

# creo la lista dei file e delle directory, a meno che non tratti di un resume
# per cui copio i file di backup nelle liste per evitare di tralasciare alcuni
# file
if [ "$RESUME_FLAG" -eq "0" ]; then
	echo -n "Sto creando la lista delle directory e dei file..."
	if ! crea_lista; then
		exit $?
	fi
	echo "terminato!"
elif [ "$RESUME_FLAG" -eq "1" ]; then
	cp -f $TEMPDIR/backup_$(basename $OKDIR)~ $OKDIR
	cp -f $TEMPDIR/backup_$(basename $SPAREFILES)~ $SPAREFILES
fi

# se è stata data l'opzione di test, allora mi fermo qui
if [ "$TEST_FLAG" -eq "1" ]; then
	echo ""
	echo "È stata data l'opzione di test, dunque non proseguirò oltre!"
	exit $E_TESTING
fi

# creo le immagini ISO necessarie al backup della directory $backdir. Finché gli elenchi
# $okdir e $sparefiles non sono vuoti, sarà necessario creare altre immagini ISO;
# andranno aggiunti file e directory alla stessa immagine, finché questa non raggiunge
# la dimensione fissata. Se una directory non entra, perché è troppo grossa per lo spazio
# restante, allora si esamina il file più grande, poi la seconda directory più grande e
# così via.

echo "Procedo alla creazione delle immagini ISO..."
echo "Per visualizzare i progressi, entra in una shell e dai il comando"
echo "tail -f "$TEMPDIR"/tar_output"

while [ -s $OKDIR -o -s $SPAREFILES ]; do
# 	creo la label e il nome dell'immagine ISO di backup,
# 	nel caso non siano stati già assegnati
	if [ ! $LABEL ]; then
		ISOLABEL="backup_$(date -d "today" +%Y%m%d)_$N"
		ISONAME="$ISOLABEL".iso
	else
		ISOLABEL=$LABEL$N
		ISONAME="$ISOLABEL".iso
	fi
	echo ""
	echo -e "\tCreo l'immagine $ISONAME..."
	while ! pieno; do
		if entra $OKDIR; then
			echo -en "\t\tSto salvando la directory"
			immagazzina $OKDIR
			K=0
			echo " terminato!"
		elif entra $SPAREFILES; then
			echo -en "\t\tSto salvando il file"
			immagazzina $SPAREFILES
			K=0
			echo " terminato!"
		fi
		if [ ! -s $OKDIR -a ! -s $SPAREFILES ]; then
			break
		fi
		let "K++"
	done
	echo "Sto creando l'immagine ISO $ISONAME..."
	echo "Per visualizzare i progressi, entra in una shell e dai il comando"
	echo "tail -f "$TEMPDIR"/"$ISONAME"_output"
	crea_iso
	let "N++"
	rm -Rf $ISODIR/*
# 	i=0
	echo -e "\tterminato!"
	echo "--> E' stata creata l'immagine ISO $ISONAME nella directory $IMGDIR,"
	echo "--> per cui si prega di procedere alla masterizzazione prima di proseguire."
	echo "--> Io restero' in attesa che tu mi dica \"prosegui\"."
	while true; do
		if [ "$QUIET_FLAG" -eq "0"  ]; then
			read SCELTA
			if [ "$SCELTA" = "prosegui" ]; then
				break
			elif [ "$SCELTA" = "termina" ]; then
				echo "Rinominerò la cartella \"$TEMPDIR\" in \"backup_$(date -d "today" +%Y%m%d)\""
				echo "così che tu possa riconoscerla facilmente"
				mv $TEMPDIR $(dirname "$TEMPDIR")/backup_$(date -d "today" +%Y%m%d)
				exit $E_PREMATURE_INTERRUPTION
			else
				echo "Scegli \"prosegui\" per continuare nella procedura di backup"
				echo "Scegli \"termina\" per terminare la procedura di backup"
				echo "Puoi sempre riprendere più tardi con \"$(basename $0) --resume\""
			fi
		elif [ "$QUIET_FLAG" -eq "1" ]; then
			break
		fi
	done
	SCELTA=""
done

echo "terminato!"

exit 0
# =======================================================================================
# fine programma principale
# =======================================================================================
  • Data: 25/03/2009
  • Autore: Tiferet
Strumenti personali
Namespace

Varianti