Linux und Windows HelpDesk

Backup und Restore einer Festplatte mit rsync per Script.

Bei dem einen ist es das "Datengrab", bei dem anderen die "Datenhure" und es gibt noch viele weitere Bezeichnungen für das Laufwerk im lokalen Netzwerk, auf dem Installationsprogramme, Konfigurationen, Dokumente, Fotos, Sicherungen von Passwörtern, Favoriten und wer weiß was noch alles, gespeichert werden. Eine automatisierte Sicherung dieses Laufwerk auf einen externen Datenträger, hat man sehr oft nicht und so kann es bei einem Hardwareausfall zu einem beträchtlichen Datenverlust kommen.
Für ein manuelles Backup oder Restore eines gesamten Laufwerk bzw. einer Partition, habe ich mir dieses Script erstellt. Ich selbst sichere damit in regelmäßig-unregelmäßigen Abständen einen Raid5-Verbund meines Server auf eine Wechsel-Festplatte.

#!/bin/bash
# ---------------------------------------------------------------
# Backup und Restore per rsync
#
# Um sicher zu gehen, daß Quelle und Ziel unter allen Umständen
# am richtigen Ort gemountet werden, wird auf das Disklabel
# zurückgegriffen. Das funktioniert auch mit udev, wenn sich ein
# anderes Device "dazwischen gedrängelt" hat und ist lesbarer
# als die UUID. Es ist ein Disklabel der Festplatte notwendig.
# Auslesen kann man das z.B. mit lsblk -o +label und verändern
# mit e2label /dev/sdxN LABEL mit tune2fs -L LABEL /dev/sdxN oder
# direkt beim Formatieren mit mkfs.ext4 /dev/sdxN -L LABEL.
# Die jeweiligen Mountpoints müssen bereits vorhanden sein.
# ---------------------------------------------------------------
# set -x
#
# Disk-Label und Mountpoint des Quelllaufwerk?
# Kein / am Ende des Pfad angeben!
LABELQ=md0
MOUNTQ=/mnt/md0
# Disk-Label und Mountpoint des Ziellaufwerk?
# Kein / am Ende des Pfad angeben!
LABELZ=backup_md0
MOUNTZ=/mnt/backup
# Wer bekommt die Mail mit den Meldungen?
EMAIL=detlef@home.lan
# Pfad zur Logdatei?
LOG=/tmp/rsync.log
#
while true; do # Schleife bis eine gültige Antwort gegeben wird.
read -p "$(echo -e '\033[32m'Backup oder Restore von $MOUNTQ starten? [B/R/'\033[4mC\033[0;32m'ancel]? '\033[0m')" -r answer
 case "$answer" in
       B|b) read -p "$(echo -e '\033[31m'Backup von $MOUNTQ auf $MOUNTZ starten? [J/N]? '\033[0m')" -r
             if [[ ! $REPLY =~ ^[Jj]$ ]]
              then
              echo "Cancel"
               exit 1
              fi
             if ! lsblk -ro MOUNTPOINT,LABEL |grep -wq "$MOUNTQ $LABELQ"
              then
               mount -L $LABELQ -t ext4 -o ro $MOUNTQ
             fi
             if ! lsblk -ro MOUNTPOINT,LABEL |grep -wq "$MOUNTZ $LABELZ"
              then
               mount -L $LABELZ -t ext4 $MOUNTZ
             fi
             if lsblk -ro MOUNTPOINT,LABEL |grep -wq "$MOUNTQ $LABELQ" && lsblk -ro MOUNTPOINT,LABEL |grep -wq "$MOUNTZ $LABELZ"
              then
               /usr/bin/rsync -avhPb --stats --delete --backup-dir=$MOUNTZ/###gelöscht###/ $MOUNTQ $MOUNTZ --log-file=$LOG
               # Die zusätzliche Option "-n" führt nur eine Simulation aus.
               echo -e "Backup von $MOUNTQ auf $MOUNTZ wurde erfolgreich abgeschlossen." | mail --attach=$LOG --subject="Backup abgeschlossen." $EMAIL;
               echo -e '\033[32m'Backup abgeschlossen.'\033[0m';
               read -s -p "Drücken Sie Enter, um fortzufahren..."
               /usr/bin/mc
               # Für eine Kontrolle den MC starten. (Zum fortfahren, mit F10 beenden.)
               rm $LOG
               umount $MOUNTQ
               umount $MOUNTZ
              else
               echo -e "Backup von $MOUNTQ auf $MOUNTZ wurde nicht durchgeführt da ein Fehler beim mounten aufgetreten ist." | mail --subject="Backup fehlgeschlagen" $EMAIL;
               echo -e '\033[31m'Backup fehlgeschlagen, fehler beim mounten.'\033[0m'
             fi
            break # Beenden der Schleife.
            ;; 
       R|r) read -p "$(echo -e '\033[31m'Restore $MOUNTQ von $MOUNTZ starten? [J/N]? '\033[0m')" -r
             if [[ ! $REPLY =~ ^[Jj]$ ]]
              then
              echo "Cancel"
               exit 1
              fi
             if ! lsblk -ro MOUNTPOINT,LABEL |grep -wq "$MOUNTQ $LABELQ"
              then
               mount -L $LABELQ -t ext4 $MOUNTQ
             fi
             if ! lsblk -ro MOUNTPOINT,LABEL |grep -wq "$MOUNTZ $LABELZ"
              then
               mount -L $LABELZ -t ext4 -o ro $MOUNTZ
             fi
             if lsblk -ro MOUNTPOINT,LABEL |grep -wq "$MOUNTQ $LABELQ" && lsblk -ro MOUNTPOINT,LABEL |grep -wq "$MOUNTZ $LABELZ"
              then
               /usr/bin/rsync -avhPb --stats --delete --backup-dir=$MOUNTQ/###gelöscht###/ $MOUNTZ/$(basename $MOUNTQ)/ $MOUNTQ --log-file=$LOG
               # Die zusätzliche Option "-n" führt nur eine Simulation aus.
               echo -e "Rücksichern von $MOUNTZ auf $MOUNTQ wurde erfolgreich abgeschlossen." | mail --attach=$LOG --subject="Restore abgeschlossen." $EMAIL;
               echo -e '\033[32m'Restore abgeschlossen.'\033[0m';
               read -s -p "Drücken Sie Enter, um fortzufahren..."
               /usr/bin/mc
               # Für eine Kontrolle den MC starten. (Zum fortfahren, mit F10 beenden.)
               rm $LOG
               umount $MOUNTQ
               umount $MOUNTZ
              else
               echo -e "Rücksicherung von $MOUNTZ auf $MOUNTQ wurde nicht durchgeführt da ein Fehler beim mounten aufgetreten ist." | mail --subject="Restore fehlgeschlagen" $EMAIL;
               echo -e '\033[31m'Restore fehlgeschlagen, fehler beim mounten.'\033[0m'
             fi
            break # Beenden der Schleife.
            ;;
       C|c) echo "Cancel"
             exit 1
            ;;
         *) echo "Unbekannter Parameter"
            ;;
 esac
done

Damit das Script sicher funktioniert, müssen die Laufwerke verschiedene Disklabel besitzen. Die Disklabel und der jeweilige Mountpoint der Festplatten, müssen im Script angegeben werden.