Organizzare un backup completo

Descrizione

Backntar v3.0 25/03/2009

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. È possibile scegliere se seguire un ordinamento alfabetico o per dimensione dei file, se i supporti devono essere riempiti al massimo e se i file devono essere compressi.

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