In der Anleitung Datensicherung mit tar habe ich Euch beschrieben, wie man mit dem Befehl 'tar' Dateien archvieren und wiederherstellen kann. Für eine tägliche Datensicherung ist es allerdings nicht praktikabel, jedesmal die Indexdatei zu kopieren oder zu löschen und den doch recht langen Befehl von Hand einzutippen.

Wir benötigen ein Script, mit dem wir das alles automatisch erledigen lassen.  Ich möchte auch anhand des Dateinamens sehen, ob es sich um eine Voll- oder inkrementelle Sicherung handelt. Das Sicherungsdatum soll ebenfalls im Namen enthalten sein. Damit ich nicht versehentlich Sicherungsdaten lösche, möchte ich die USB-Platte nur für die Sicherung mounten und anschließend wieder dismounten.

Grundsätzliches zu Scripts

Den folgenden Text habe ich http://www.bin-bash.de/scripts.php entnommen:

"Wir schreiben in die erste Zeile:

#!/bin/bash

Diese Zeile wird auch Shebang genannt und definiert mit welchem Kommandointerpreter (also welcher Shell) das Script ausgewertet werden soll. Wenn wir das Script auch für andere Unix-Systeme (wie z. B. BSD) kompatibel halten wollen, können wir auch statt /bin/bash, /bin/sh schreiben. Allerdings bietet die Bash einige Funktionen an, die die Sh nicht kennt. Diese dürfen dann natürlich auch nicht verwendet werden.

Grundsätzlich gilt: Zeilen die mit # beginnen sind Kommentarzeilen und werden nicht ausgewertet. Die erste Zeile mit dem Shebang ist dabei eine Ausnahme. Zur Übersichtlichkeit können Sie außerdem an beliebigen Stellen Leerzeilen einfügen."

Das folgende Script sichert ausgewählte Ordner im Verzeichnis /home. Über einen Parameter wird angegeben, ob eine volle oder inkrementelle Sicherung durchgeführt wird. Die Ordner werden einfach hintereinander als weitere Parameter angegeben.

#!/bin/bash

# ./backup.sh

#####################################################################
# Datensicherung /home
#
# Es werden ausgewählte Verzeichnisse unterhalb von /home
# gesichert.
# Die Verzeichnisse werden als Parameter, durch Leerzeichen getrennt,
# angegeben.
#
# Bei Angabe des Parameters '-f' wird
# eine Vollsicherung durchgeführt, sonst
# wird - sollte eine timestamp-Datei vorhanden sein -
# inkrementell gesichert.
#
# Beispiel: ./backup.sh -f Bibo Willi sysadmin Allgemein Media
#
# Sicherungsdateien werden mit aktuellem Datum im Namen versehen
#
# Das Script soll automatisch via crontab aufgerufen werden.
# Daher werden alle Ausgaben in eine Logdatei gelenkt.
#
# (c) 2011 Exilschwälmer
####################################################################

# Variablen definieren

ba_basis=/home
ba_dir=/media/sicherung
ba_old=/media/sicherung/old
ba_logdir=/media/sicherung/log
ba_name=ba_
ba_sfx=tar.gz
ba_datum=_$(date +%Y%m%d%H%M)

# Sicherungsplatte mounten
# mount $ba_dir

# Wenn erster Parameter '-f', wird auf jeden Fall eine Vollsicherung gemacht

if [ $1 = -f ] ; then
echo "Vollbackup!"
# Variable setzen und Parameter 'shiften'
ba_type=full_
shift
else
ba_type=incr_
fi

# Wenn keine Parameter angegeben wurden: Fehlermeldung

if [ $# -lt 1 ]; then
echo "Nichts zum sichern angegeben!"
echo "Aufruf: $0 [-f] Verzeichnis1 Verzeichnis2 ... VerzeichnisX"
exit 1
fi

# Jetzt wird in einer Schleife jedes Verzeichnis, das als Parameter angegeben wurde, gesichert

while [ $# -gt 0 ]
do
ba_target=$1

# Checken, ob das zu sichernde Verzeichnis überhaupt existiert

if [ -d $ba_basis/$ba_target ]; then

# Logdatei

log=$ba_logdir/$ba_target$ba_datum.log

echo -e "Verzeichnis: $ba_basis/$ba_target wird gesichert!\n" >> $log
# Startzeit (UTC)  für Laufzeitermittlung sichern und auch in die Logdatei schreiben

beginn=$(date +%s)
echo -e "Beginn: $(date "+%d %b %Y %T")\n" >> $log

# Wenn eine Vollsicherung durchgeführt werden soll, löschen wir einfach die timestamp-Datei
# Evtl. vorhandene ältere Sicherungen werden nach $ba_old verschoben und müssen bei Bedarf
# von Hand gelöscht werden.

# Auch ohne den Parameter '-f' wird eine Vollsicherung gemacht, wenn die Timestamp-Datei
# nicht vorhanden ist. Bei fehlender Timestamp-Datei wird deshalb $ba_type auch auf 'full_'
# gesetzt.

if ! [ -f $ba_dir/ts_$ba_target ]; then
ba_type=full_
fi

if [ $ba_type = "full_" ] ; then
if [ -f $ba_dir/ts_$ba_target ]; then
rm $ba_dir/ts_$ba_target
fi
mv $ba_dir/$ba_name?????$ba_target* $ba_old
fi

# Archivname: ba_full_Ordner_YYYYMMDDhhmm.tar.gz (ba_incr_...)
# Timestampdatei: ts_Ordner
# Inkrementelle Sicherungen werden immer auf Basis der letzten Vollsicherung gemacht.
# Deshalb wird die Timestamp-Datei gesichert und nach der inkr.Sicherung wieder zurückgespielt

if [ -f $ba_dir/ts_$ba_target ]; then
cp $ba_dir/ts_$ba_target $ba_dir/ts_$ba_target.sik
fi

tar -zcvf $ba_dir/$ba_name$ba_type$ba_target$ba_datum.$ba_sfx $ba_basis/$ba_target -g $ba_dir/ts_$ba_target >> $log

if [ -f $ba_dir/ts_$ba_target.sik ]; then
rm $ba_dir/ts_$ba_target
mv $ba_dir/ts_$ba_target.sik $ba_dir/ts_$ba_target
fi


# Prüfen, ob das Archiv ok ist

gz_text=$(gzip -t $ba_dir/$ba_name$ba_type$ba_target$ba_datum.$ba_sfx 2>&1)

case "$?" in

0)
echo -e "\nArchivdatei $ba_dir/$ba_name$ba_type$ba_target$ba_datum.$ba_sfx fehlerfrei erstellt!\n" >> $log ;;
1)
echo -e "\nArchivdatei $ba_dir/$ba_name$ba_type$ba_target$ba_datum.$ba_sfx ist fehlerhaft!\n" >> $log ;;
2)
echo -e "\nArchivdatei $ba_dir/$ba_name$ba_type$ba_target$ba_datum.$ba_sfx mit Warnmeldung!\n" >> $log ;;
*)
echo "Das sollte nicht passieren ;-)" ;;
esac

# Falls gzip eine Fehlermeldung gegeben hat, wird sie ins Log geschrieben.

echo $gz_text >> $log

# Endzeit ermitteln und Laufzeit berechnen, alles ins Logfile schreiben
# Hint: Der Bash wird durch doppelte Klammern '((' gesagt, daß gerechnet werden soll
# Das Prozentzeichen beim Ausrechnen der Stunden, Minuten und Sekunden ergibt den Rest
# der Division (Modulo-Division)

ende=$(date +%s)
echo -e "Ende: $(date "+%d %b %Y %T")\n" >> $log

lz=$((ende - beginn ))
echo -e "Laufzeit: $((lz /3600)) Std. $((lz % 3600 /60)) Min. $((lz % 60)) s." >> $log

else
echo "Verzeichnis: $ba_basis/$ba_target existiert nicht und wird übersprungen!"
fi
shift
done

# Sicherungsplatte dismounten
# umount $ba_dir

# Ende und ohne Fehler raus
exit 0

Anmerkung: Mount/Dismount der Sicherungsplatte ist noch auskommentiert. Man will ja schließlich erst mal das Ergebnis prüfen. Wenn alles wie gewünscht funktioniert, werden die Funktionen aktiviert und das Ganze in die Crontab gepackt. Darum geht's im nächsten Teil.

Downloadbackup.sh

In dem angehängten Script ist das Mounten vor und Dismounten nach dem Backup bereits aktiviert!

Zusätzliche Informationen