Home / User-Blogs / Marcus Nasarek / Backups mit tar

Backups mit tar

→ Zum Blog von Marcus Nasarek

Es gibt hunderte Programme, mit denen man Backups erstellen und verwalten kann. Mit und ohne GUI, komplett, inkrementell oder differenziell geschnitten oder am Stück. Ich schau mir solche Programme an, finde sie toll...und benutze sie nicht. Warum tue ich mich so schwer damit, endlich mal ein richtig komfortables Programm für diese so wichtige Aufgabe ins Boot zu holen?

Vielleicht, weil ich Distributionsnomade bin. Hier mal Suse ausprobiert, da mal Ubuntu und meist doch wieder zu Zenwalk gefunden. Und immer müssen die Archive mit. Ich brauch daher ein universelles Backup-Tool, am besten eins, das bei allen Distributionen on board ist. Und irgendwie komme ich dann immer (noch) auf tar. Klein und mächtig - ein Begriff von mächtig kann man sich beim Anblick des Handbuchs machen, das ganze 230 A4-Seiten umfasst - und dabei einfach zu handhaben. Naja, nachdem man das Handbuch gelesen hat.

Ein bißchen Komfort will ich dann doch, und baue mir ein Skript um ein paar tar-Kommandos. Mit denen kann ich ein neues Archiv erstellen und neuere Dateien inkrementell hinzufügen. So sind die verschiedenen Versionen der geänderten Dateien im Archiv enthalten und ich kann später auf einen beliebigen Zeitpunkt zurückgreifen.

Hier das Skript backup.sh:

 #!/bin/bash
# Funktion für die Hilfe
function help() {
    echo -e "Verwendung: $0 <archiv.tar> <sourcedir>"
    echo -e "\tHinweis: $1"
}

# Zeitpunkt des letzten Backups herausfinden, ist die letzte Zeile im Script
LASTBACKUP=`tail -n 1 $0 | egrep "^# [0-9]{4}" | cut -c 3-`

# Endet die Archivdatei mit "tar"?
if [ "${1: -3:3}" = "tar" ];
then
    BACKUPFILE="$1";
else
    help "Kein Tar-Archiv angegeben."
    exit;
fi

# Verzeichnis, das archiviert werden soll
if [ -d "$2" ];
then
    SOURCE="$2"
else
    help "Kein Verzeichnis angegeben, dass gesichert werden soll."
    exit;
fi

# bestimmte Dateien und Verzeichnisse ausschließen
EXCLUDES="--exclude=Images --exclude=Cache --exclude=*.vdi --exclude=cache"

# Lesefehler ignorieren und Besitzer-IDs numerisch aufnehmen
TAROPTIONS="--ignore-failed-read --numeric-owner"

if [ "$LASTBACKUP" ];
then
    # Falls es schon ein Backup gab, Zeitpunkt ausgeben
    echo ">> last backup at :$LASTBACKUP:"
    # ... außdem neue Dateien hinzufügen und Zeitstempel aktualisieren
    tar uvf "$BACKUPFILE" "$SOURCE" $TAROPTIONS $EXCLUDES --newer-mtime "$LASTBACKUP"
    # Zeitstempel aktualisieren
    echo "# `date +'%F %T'`" >> $0;
else
    # Falls es noch kein Backup gibt, eins erzeugen
    tar cvf "$BACKUPFILE" "$SOURCE" $TAROPTIONS $EXCLUDES
    echo "# `date +'%F %T'`" >> $0;
fi

# 2009-03-15 22:33:26

Im Skript verwende ich einen Zeitstempel, der als letzte Zeile in das Skript eingetragen wird. Da ich das Backup-Skript nur für die Sicherung meines home-Verzeichnisses nutze, ist das ok. Ansonsten würde ich den Zeitstempel und den Namen des jeweiligen Archives in eine eigene Datei auslagern. So sieht dann ein Aufruf aus:

u0001@SAMS:~$ ./bin/backup.sh test.tar bin/
bin/
bin/btscoHelper.sh
bin/offers.txt
bin/test.sh
bin/genOffers.rb
bin/findBackup.sh
bin/backup.sh
bin/countSize.rb
u0001@SAMS:~$

Und mit dem folgenden Skript findBackup.sh finde ich eine einzelne Datei wieder. Da von einer Datei mehrere Versionen im Archiv liegen können, werden die Fundstellen numeriert:

 #!/bin/bash
function help() {
    echo "Verwendung: $0 <archive.tar> <pattern>"
    echo -e "\twobei <pattern> Teil des Datei- oder Verzeichnisnamen ist,"
    echo -e "\tnachdem in <archive.tar> gesucht werden soll."
    echo -e "\tHinweis: $1"
}

# Archivdatei (Endung des ersten Parameter prüfen)
if [ "${1: -3:3}" = "tar" ];
then
    BACKUPFILE="$1";
else
    help "Kein tar-Archive angegeben."
    exit;
fi

# Mit Wildcards suchen, Groß- und Kleinschreibung ignorieren und 
# auch Teilmuster finden
TAROPTIONS="--wildcards --ignore-case --no-anchored"

# Anzahl der Argumente prüfen, bei Bedarf helfen
if [ $# -lt 2 ];
then
    help "Nur $# Argumente angegeben. Brauche 2."
    exit
fi

# Das Suchmuster mit wildcards umgeben
PATTERN="*$2*"

# Pattern ausgeben
echo Suche nach "$PATTERN"

# Suchen und nummeriert ausgeben (die Aufgabe übernimmt ein awk-Skript :-))
tar tvf $BACKUPFILE $TAROPTIONS $PATTERN | awk 'BEGIN{lnr=1}/^[-rwxd]/{print lnr, $0;lnr=lnr+1}'

Eine Suche nach einer Datei, in deren Name die Zeichenkette "backup" enthalten ist, sieht dann so aus:

u0001@SAMS:~$ ./bin/findBackup.sh test.tar backup
Suche nach *backup*
1 -rwxr-xr-x 1000/1000      1039 2009-03-13 21:25 bin/findBackup.sh
2 -rwxr-xr-x 1000/1000      1258 2009-03-14 22:33 bin/backup.sh
3 -rwxr-xr-x 1000/1000      1280 2009-03-15 22:35 bin/backup.sh
u0001@SAMS:~$

Um nun gezielt eine bestimmte Version einer Datei zu extrahieren, gibt man die Nummer der gewünschten Fundstelle an:

tar xvf <archive.tar> <Datei> --occurrence=<num>

Die Datei oder das Verzeichnis, das extrahiert werden soll, muss natürlich mit der kompletten Pfadangabe angegeben werden. Sonst kann tar den Eintrag nicht finden. So, das war's. Backup erstellen, updaten und wiederherstellen. Mehr wollte ich eigentlich nicht... Und tar findet sich hoffentlich auf jeder Distribution.

Bookmark and Share

Kommentare
Ideal als cron-Job
Axel Konrad, Sonntag, 22. März 2009 21:46:39
Ein/Ausklappen

Hallo Marcus,

habe mir vor zwei Jahren auch ein kleines backup-Skript mit tar geschrieben. Aber ich muss zugeben Deines ist um Klassen besser, besonders die Ergänzung um "findbackup".
Ich finde einfach die Kombination ein Skript selbst zu schreiben und es als cron-Job laufen zu lassen ideal.

Wenn Du weitere gute Ideen hast, lasse es die Community wissen.

Ich sage jedenfals schon mal Danke.

Gruß von scholle1


Bewertung: 203 Punkte bei 11 Stimmen.
Den Beitrag bewerten: Gut / Schlecht

2978 Hits
Wertung: 217 Punkte (22 Stimmen)

Schlecht Gut

Infos zum Autor