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.
# -----------------------------------------------------------------------------------------
# set -x
#
# Disk-Label und Mountpoint des Quelllaufwerk. (Der Mountpoint muss vorhanden sein.)
# Kein / am Ende des Pfad angeben!
LABELQ=md0
MOUNTQ=/mnt/md0
# Disk-Label und Mountpoint des Ziellaufwerk. (Der Mountpoint muss vorhanden sein.)
# 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..." -r
        /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..." -r
        /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.