Verzeichnisinhalte auslesen und übersichtlich als Mail verschicken

Datensicherungen sind das A und O eines Produktivservers. Auch im heimischen Netzwerk sollten Daten und Dokumente regelmäßig gesichert werden, denn es gibt nur wenige Dinge im Leben, die noch schlimmer sind als beispielsweise der Verlust sämtlicher digitaler Urlaubsfotos. Wer nicht auf teure und komplexe Sicherungsprogramme zurückgreifen möchte, der kann unter Linux mit dem Archivprogramm tar in Verbindung mit cron auf bequeme Art und Weise Sicherungen erstellen. Tar erstellt das Backup-Archiv und cron sorgt dafür, dass die Sicherung regelmäßig durchgeführt wird.

Was passiert aber, wenn die Datensicherung nicht mehr durchgeführt wird, weil irgendein Problem aufgetreten ist. Es ist auf Dauer ziemlich lästig, die Datensicherungen manuell zu überprüfen, indem man jedes zu sichernde Verzeichnis öffnet. Problematisch wird es, wenn man beispielsweise mehrere Remote-Server administriert, so dass man sich erst mit jedem Server verbinden muss. Einfacher wäre es, wenn der Admin automatisch per Mail über die Datensicherung informiert wird und die Sicherungsdateien übersichtlich aufgelistet werden.

Folgendes Skript liest die Dateien aus bestimmten Verzeichnissen heraus und versendet die wichtigsten Daten als Mail.

Ausgangslage

In einem zentralen Verzeichnis befinden sich mehrere Unterverzeichnisse, welche die Sicherungen enthalten:

-- rechner-1
----- home.tar.gz
----- rechnungen.tar.gz
----- bilderalbum.tar.gz

-- rechner-2
----- home.tar.gz
----- rechnungen.tar.gz
----- sonstiges.tar.gz

-- rechner-3
----- home.tar.gz
----- rechnungen.tar.gz
----- mysql.sql

-- rechner-4
----- home.tar.gz
----- rechnungen.tar.gz
----- mysql.sql

In diesem Beispiel wird also für jeden Netzwerkrechner ein Verzeichnis angelegt, in welchem die Datensicherungen gespeichert werden. Voraussetzung ist, dass die Datensicherungen jedes einzelnen Clients in dem Verzeichnis gespeichert werden.

Ziel soll es nun sein, dass mit einem automatisierten Skript die Verzeichnisse ausgelesen und übersichtlich dargestellt werden.

Umsetzung: das Linux-Skript zur Statusmeldung der Datensicherung

Bevor die Vorgehensweise erklärt wird, soll erst einmal das komplette Skript vorgestellt werden:

# Definition der Variable lokal, welche auf die Textdatei verweist
lokal="/tmp/backup-groesse.txt"

# In das Vrz. mit den Datensicherungen wechseln
cd /home/backup/

# freien Speicherplatz anzeigen
echo "Speicherplatz" > ${lokal}
echo "=========================================" >> ${lokal}
df -h | grep Filesystem >> ${lokal}
df -h | grep md2 >> ${lokal}
echo " " >> ${lokal}

# Sicherungen aus den einzelnen Verzeichnissen generieren
for TREFFER in $(ls | grep rechner)
do

echo "Tagessicherung: $TREFFER" >> ${lokal}
echo "=========================================" >> ${lokal}

ls -lsh $TREFFER | awk '{print $9" / "$8" "$7"\t"$10" ["$1"]"}' >> ${lokal}

echo " " >> ${lokal}

done

cat ${lokal} | mutt -s "Status Backup $HOSTNAME" "abc@gmx.de" -c "xyz@gmx.de"

Erklärung: Das Grundprinzip ist relativ einfach, denn wir benutzen die hauseigenen Linux-Tools wie ls, grep, df und awk. Sämtliche Ausgaben werden in eine Textdatei geschrieben, welche zum Schluss als Email versendet wird. Wichtig ist, dass die allererste Ausgabe mit einem einfachen > (alter Inhalt wird überschrieben) und die darauf folgenden Ausgaben mit einem >> (neuer Inhalt wird angehangen) in die Textdatei geschrieben werden.

# Definition der Variable lokal, welche auf die Textdatei verweist
lokal="/tmp/backup-groesse.txt"

# In das Vrz. mit den Datensicherungen wechseln
cd /home/backup/

# freien Speicherplatz anzeigen
echo "Speicherplatz" > ${lokal}
echo "=========================================" >> ${lokal}

Die Ausgabe wird also in die Textdatei /tmp/backup-groesse.txt geschrieben, welche wir anfangs als Variable lokal definiert haben.

1 Schritt: freien Speicherplatz ermitteln

df steht für Disk Free und ermittelt den freien Speicherplatz. Die Option -h (human readable) zeigt uns den Speicherplatz in menschen-lesbarer Form wieder, so dass wir mit grep die passenden Zeilen herauslesen. In diesem Fall lautet das Device /dev/md2, könnte aber genauso gut /dev/hda3 oder /dev/sda3 lauten.

df -h | grep Filesystem >> ${lokal}
df -h | grep md2 >> ${lokal}

Das wäre die Ausgabe:

Speicherplatz
=========================================
Filesystem Size Used Avail Use% Mounted on
/dev/md2 148G 67G 81G 46% /

2. Schritt: Sicherungen aus den einzelnen Verzeichnissen auslesen

Im nächsten Schritt sollen die Sicherungen aus den Verzeichnissen recher-1, rechner-2, usw. ausgelesen werden. Diese Verzeichnisse statisch in das Skript einzupflegen, wäre mit Mehrausfwand verbunden, denn mit jedem neuen Rechner müsste das Skript angepasst werden. Einfacher ist es, eine Schleife zu verwenden:

for TREFFER in $(ls | grep rechner)
do

.... tue irgendwas

done

Wichtig ist der Befehl ls | grep rechner. Dieser Befehl listet alle Dateien auf, welche den String rechner enthalten. In unserem Beispiel werden also alle Verzeichnisse rechner-1, rechner-2, usw. aufgelistet, alle anderen nicht. Für jedes gefundene Verzeichnis wird der Inhalt der Schleife (...tue irgendwas ausgeführt). Die Variable TREFFER speichert den aktuellen Suchtreffer, also das gefundene Verzeichnis.

  ls -lsh $TREFFER

In der Schleife können wir nun mittels $TREFFER auf die Variable zugreifen und beispielsweise den Inhalt des Verzeichnisses anzeigen. ls -lsh zeigt aber sehr viele Informationen an. Viele davon sind "überflüssig", so dass wir mit awk nur bestimmte Spalten selektieren:

ls -lsh $TREFFER | awk '{print $9" / "$8" "$7"\t"$10" ["$1"]"}' >> ${lokal}

Das Prinzip von awk lässt sich folgendermaßen erklären: ls gibt die Ausgabe in Spalten an. Mit awk kann man nun auf die Spalten zugreifen, welche als $1, $2, ..., $m dargestellt werden. In oben genannten Beispiel werden also nur die Spalten 9, 8, 7, 10 und 1 selektiert.  In den Hochkommatas kann man zusätzlichen Text festlegen, um die Ausgabe übersichtlicher zu formatieren.

Dieses Beispiel ergibt folgende Ausgabe:

Tagessicherung: rechner-1
=========================================
/ [total]
13:12 / 10 Sep home.tar.gz [236M]
13:13 / 10 Sep rechnungen.tar.gz [13M]
13:12 / 10 Sep bilderalbum.tar.gz [509M]

Letztendlich verwenden wir noch mutt, um die Daten per Mail zu verschicken:

cat ${lokal} | mutt -s "Status Backup $HOSTNAME" "abc@gmx.de" -c "xyz@gmx.de"

Fazit

Linux-Scripting ist nicht schwer. Mit einfachen Linux-Programmen kann man einfache Statusmeldungen programmieren. Probiert das Skript einfach mal aus und testet die Funktionen. Bei der Entwicklung ist es ratsam, die Ausgabe nicht in eine Textdatei zu schreiben.