Hier ist die Musterlösung zu Aufgabe: Automatisches Backup: fullbackup_install.
Das Skript hat vor dem Installieren den Namen fullbackup_install, uns installiert sich selbst, wenn es mit diesem Namen aufgerufen wird.
Der erhoffte Lernerfolg dieser Musterlösung:
$0) bekommt man nicht zum Vergnügen immer übergeben, sondern man darf ihn auch
ruhig mal verwenden
#!/bin/sh # ##################################################################### # # Time-stamp: "29.09.02 15:52 fullbackup_install klaus@wachtler.de" # ##################################################################### # # /etc/backup/fullbackup # /etc/backup/append -> /etc/backup/fullbackup # /etc/backup/delete -> /etc/backup/fullbackup # /etc/backup/du -> /etc/backup/fullbackup # /etc/backup/incrbackup -> /etc/backup/fullbackup # /etc/backup/incrrestore -> /etc/backup/fullbackup # /etc/backup/list -> /etc/backup/fullbackup # /etc/backup/rewind -> /etc/backup/fullbackup # # fullbackup macht ein volles Backup aller Verzeichnisse (ab /), # die in $ZUSICHERN aufgeführt sind. # Datum und Uhrzeit (vor der Sicherung) # werden in /etc/backup/lastfull und # /etc/backup/lastincr festgehalten. # Nachfolgende inkrementelle Sicherungen können sich also auf # /etc/backup/lastincr beziehen, und diese dann # aktualisieren. # # /etc/backup/lastincr und /etc/backup/lastfull # werden vor der Sicherung als # /etc/backup/lastincr.tmp und /etc/backup/lastfull.tmp # angelegt, und erst bei Erfolg umbenannt. # # # Wenn der Name, mit dem das Skript aufgerufen wird, auf # "incrbackup" endet, dann wird nur ein inkrementelles # Backup durchgeführt. # Wenn das Skript also als "/etc/backup/fullbackup" # gespeichert ist, und man mit # "cd /etc/backup/; ln -s fullbackup incrbackup" # einen Link darauf anlegt, dann wird -wenn # /etc/backup/incrbackup aufgerufen wird- nur # ein inkrementelles Backup durchgeführt. # # In diesem Fall verhält sich das Skript etwas anders: # # - Die Meldungen lauten etwas anders # # - Es wird nicht die Merkerdatei "$MERKERFULL" # aktualisiert, sondern nur "$MERKERINCR". # # - Das Band wird vor der Sicherung ans Ende gespult # # - für die Sicherung wird nicht $TAPE, sondern $NTAPE verwendet. # Dadurch kann für die inkrementellen Sicherungen ein Band # durchgehend im Laufwerk bleiben (wenn $NTAPE nicht automatisch # an den Anfang gespult wird). Alle inkrementellen Sicherungen # kommen dann hintereinander auf ein Band, bis ein Schreibfehler # auftritt. Erst dann muß von Hand das Band gewechselt werden. # # - es werden nicht alle Dateien gesichert, sondern # nur diejenigen, welche seit dem Anlegen von # "$MERKERINCR" modifiziert wurden # # # Endet der Skriptname auf "restore", dann wird das Band an den # Anfang gespult, und solange von /dev/ntape tar-Archive gelesen, # bis ein Fehler auftritt. # Dazu kann man wieder einen symbolischen Link verwenden: # "cd /etc/backup/; ln -s fullbackup incrrestore" # # # Endet der Skriptname auf "rewind", dann wird das Band an den # Anfang gespult. # # # Endet der Skriptname auf "list", dann wird der Bandinhalt # gelistet, und das Band an das Ende der Daten gespult. # # # Endet der Skriptname auf "append", dann wird das Band an das # Ende der Daten gespult. # # # Endet der Skriptname auf "delete", dann wird das Band gelöscht. # # # Endet der Skriptname auf "du", dann wird festgestellt, wieviel # Speicherplatz auf dem Band für eine Vollsicherung benötigt wird. # # # Vorgesehene Verwendung: # # 0) mit ./fullbackup_install wird das Skript installiert und # die Links werden angelegt # # 1) gelegentlich wird ein ausreichend großes Band eingelegt, # und manuell eine Vollsicherung gestartet (mit # "/etc/backup/fullbackup") # # 2) Ein weiteres Band für inkrementelle Sicherungen verbleibt # im Laufwerk. # Über den cron-Dämon wird beispielsweise jede # Nacht eine inkrementelle Sicherung angeworfen (mit # "/etc/backup/incrbackup"). # Beispieleintrag für /etc/crontab: # # automatisches inkrementelles Backup: # 0 4 * * * root /etc/backup/incrbackup # Damit wird jeden morgen um 4:00 ein inkrementelles Backup # gestartet. # Wenn das Band (für die inkrementellen Sicherungen) voll ist, # muß man entweder: # a) ein neues Band einlegen, und eine Vollsicherung starten # (mit /etc/backup/fullbackup), # danach ein leeres Band für die inkrementellen Sicherungen # (ggf. mit /etc/backup/delete löschen) im # Laufwerk liegen lassen. # Damit beginnt der Zyklus von vorne. # oder: # b) Die letzte Vollsicherung behalten, die Kassette mit den # bisherigen ersten inkrementelle Sicherungen als solche # kennzeichnen, # und eine weitere Kassette für die kommenden inkrementellen # Sicherungen ggf. löschen und im Laufwerk lassen. # # Zum Restaurieren aller Daten geht man in ein Verzeichnis mit # reichlich Platz und macht folgendes: # 1) Kassette mit der Vollsicherung einlegen # 2) /etc/backup/incrrestore # 3) Nacheinander für alle Kassetten mit den inkrementellen # Sicherungen (in der richtigen Reihenfolge!) # a) Kassette einlegen # b) /etc/backup/incrrestore # 4) Wenn man die letzte Kassette jetzt wieder für die nächsten # inkrementellen Sicherungen verwenden will: # a) diese Kassette einlegen # b) an das Ende der Daten spulen (inzwischen überflüssig): # /etc/backup/append # # Alternativ kann man (wenn man nur eine Datei bzw. wenige wieder # restaurieren möchte) anhand der Inhaltsverzeichnisse aller Bänder # (abgelegt in /home/dir/tape*.dir.gz) nach den neuesten Sicherungen # der Datei(en) suchen, und von Hand mit tar entpacken. # ##################################################################### # # Änderungen: # # 31.04.2000 kw - Selbstinstallierend # - Vor einer inkrementellen Sicherung wird das # Band automatisch ans Ende gespult # (falls der Rechner neu geboootet hat, oder # jemand das Band aus dem Laufwerk genommen hatte, # dann mußte man bisher daran denken, das Band # ans Ende zu spulen, um nicht schon bestehende # Sicherungen am Anfang des Bandes zu # überschreiben. # Das geschieht jetzt automatisch vor jeder # inkrementellen Sicherung.). # Folge: Will man auf einem bereits beschriebenen # Band mit inkrementellen Sicherungen neu beginnen, # dann muß das Band vorher gelöscht werden, sonst # würde die erste Sicherung ja am Ende angefügt # werden (falls da überhaupt Platz ist). # - Zum Löschen des Bandes gibt es dafür jetzt # das Kommando /etc/backup/delete. # - Weitere neue Kommandos: # /etc/backup/append: spult das Band ans Ende # /etc/backup/rewind: spult das Band an den Anfang # /etc/backup/list: # # 02.05.2000 kw Nach der vollen Sicherung bleibt das Band am Ende # stehen. # Es wird nur noch $NTAPE verwendet, $TAPE ist # überflüssig geworden. # # # 18.05.2001 kw Bei der Installation wird das Verzeichnis für # die Inhaltsverzeichnisse angelegt # ##################################################################### # # Einstellbare Variablen:
# Liste der zu sichernden Verzeichnisse (ab /, anzugeben ohne
# führenden Schrägstrich, mehrere Verzeichnisse getrennt mit
# Leerzeichen).
# Beispiel:
# ZUSICHERN="home root var/spool/mail etc usr/local"
#
# (ZUSICHERN wird nur gesetzt, wenn es nicht schon beim Aufruf des
# Skripts gesetzt ist)
ZUSICHERN=${ZUSICHERN-"home root var/spool/mail etc usr/local"}
# zu verwendendes Laufwerk:
# Band wird NICHT an den Anfang gespult!
NTAPE=/dev/ntape
# Pfad für die Inhaltsverzeichnisse aller Bänder:
VERZEICHNIS_FUER_INHALTSVERZEICHNIS=/home/dir
# Benutzer und Gruppe, auf die das Inhaltsverzeichnis gesetzt werden
# soll (mit anderen Worten: wer darf die Inhaltsverzeichnisse
# sehen?):
DIRUSR=root
DIRGRP=users
# Merkerdateien für Datum der letzten vollen/inkr. Sicherung:
MERKERFULL=/etc/backup/lastfull
MERKERINCR=/etc/backup/lastincr
# Protokolldatei:
LOGFILE=/etc/backup/backup.log
# Verzeichnis für dieses Skript und die Links:
INSTALLDIR=/etc/backup
#
#####################################################################
STARTSTRING=`date +"%Y%m%d_%H%M"`
if [ `echo $0|grep '.*install$'` ]
then
echo "Installation von $INSTALLDIR/fullbackup"
if [ `whoami` != "root" ]
then
echo "Fehler: Installation nur als root möglich!"
exit 1
fi
# evtl. alten Müll wegwerfen:
rm -f $INSTALLDIR/append
rm -f $INSTALLDIR/delete
rm -f $INSTALLDIR/du
rm -f $INSTALLDIR/incrbackup
rm -f $INSTALLDIR/incrrestore
rm -f $INSTALLDIR/list
rm -f $INSTALLDIR/rewind
# Verzeichnis anlegen:
mkdir -m 700 -p $INSTALLDIR 2>/dev/null
echo Verzeichnis $INSTALLDIR angelegt
# Verzeichnis für Inhaltsverzeichnisse anlegen:
mkdir -m 700 -p $VERZEICHNIS_FUER_INHALTSVERZEICHNIS 2>/dev/null
echo Verzeichnis $VERZEICHNIS_FUER_INHALTSVERZEICHNIS angelegt
# Das Skript selbst dahin kopieren:
cp $0 $INSTALLDIR/fullbackup
chown root:root $INSTALLDIR/fullbackup
chmod 500 $INSTALLDIR/fullbackup
# Und weitere Links darauf anlegen:
cd $INSTALLDIR
ln -s fullbackup append
echo "link angelegt: $INSTALLDIR/append"
ln -s fullbackup delete
echo "link angelegt: $INSTALLDIR/delete"
ln -s fullbackup du
echo "link angelegt: $INSTALLDIR/du"
ln -s fullbackup incrbackup
echo "link angelegt: $INSTALLDIR/incrbackup"
ln -s fullbackup incrrestore
echo "link angelegt: $INSTALLDIR/incrrestore"
ln -s fullbackup list
echo "link angelegt: $INSTALLDIR/list"
ln -s fullbackup rewind
echo "link angelegt: $INSTALLDIR/rewind"
true
exit
fi
if [ `echo $0|grep '.*du$'` ]
then
echo "Ermitteln des Platzbedarfs..."
( cd /; du -c $ZUSICHERN )
true
exit
fi
if [ `echo $0|grep '.*restore$'` ]
then
echo "Zurückspulen des Bandes..."
$INSTALLDIR/rewind
echo "Entpacken aller Archive von $NTAPE ins aktuelle"
echo "Verzeichnis,"
echo "bis ein Fehler auftritt..."
true
erg=$?
while [ $erg == "0" ]
do
tar xvf $NTAPE 2>/dev/null
erg=$?
if [ $erg == "0" ]
then
echo
echo " ##### Sicherungssatz gefunden #####"
echo
else
echo
echo "Ende der Sicherungen?"
echo "Das Band steht am Ende der Daten."
fi
done
echo "Ende des Zurückladens vom Band."
exit
fi
if [ `echo $0|grep '.*delete$'` ]
then
echo "Löschen des Bandes..."
mt -f $NTAPE erase
echo "Fertig!"
exit
fi
if [ `echo $0|grep '.*rewind$'` ]
then
echo "Zurückspulen des Bandes..."
mt -f $NTAPE rewind
echo "Ende des Zurückspulens."
exit
fi
if [ `echo $0|grep '.*list$'` ]
then
echo "Zurückspulen des Bandes..."
$INSTALLDIR/rewind
echo "Listen aller Archive von $NTAPE,"
echo " bis ein Fehler auftritt..."
true
erg=$?
while [ $erg == "0" ]
do
tar tvf $NTAPE 2>/dev/null
erg=$?
if [ $erg == "0" ]
then
echo
echo " ##### Sicherungssatz gefunden #####"
echo
else
echo
echo "Ende der Sicherungen?"
echo "Das Band steht am Ende der Daten."
fi
done
echo "Ende des Inhaltsverzeichnisses vom Band."
exit
fi
if [ `echo $0|grep '.*append$'` ]
then
echo "Spulen des Bandes ans Ende..."
mt -f $NTAPE eom
echo "fertig!"
exit
fi
if [ `echo $0|grep '.*incrbackup$'` ]
then
# Programmname endet auf "incrbackup", also nur
# inkrementelles Backup:
incrbackup="y"
unset fullbackup
TEXT="INKREMENTELLES BACKUP"
text="Inkrementelles Backup"
NAME=tape.$STARTSTRING.incr
mt -f $NTAPE eom
else
# Programmname endet NICHT auf "incrbackup", also
# volles Backup:
unset incrbackup
fullbackup="y"
TEXT="VOLLBACKUP"
text="Vollbackup"
NAME=tape.$STARTSTRING
mt -f $NTAPE rewind
fi
DIRFILE=$NAME.dir
cd /
# die Merkerdateien erstmal provisorisch anlegen
# (mit Datum/Uhrzeit vom Backupstart):
echo $STARTSTRING >$MERKERINCR.tmp
if [ $fullbackup ]
then
echo $STARTSTRING >$MERKERFULL.tmp
fi
echo "" >>$LOGFILE
echo "------------------------------------------" >>$LOGFILE
echo "" >>$LOGFILE
echo $text" " `date +"%A %d.%m.%Y %H:%M"` >>$LOGFILE
echo "(Rechner: " `uname -a` ")" >>$LOGFILE
echo "" >>$LOGFILE
if [ $fullbackup ]
then
# Volles Backup
tar cvf $NTAPE \
$ZUSICHERN \
-V "$NAME" \
>$DIRFILE 2>>$LOGFILE
else
# Inkrementelles Backup
find $ZUSICHERN -newer $MERKERINCR -and -type f -print0 |\
tar cvf $NTAPE -V $NAME --null -T /dev/stdin \
>$DIRFILE 2>>$LOGFILE
fi
if [ $? != "0" ]
then
# tar meldet einen Fehler
echo "ABBRUCH! ("`date +"%d.%m.%Y %H:%M"`")" >>$LOGFILE
echo "" >>$LOGFILE
rm -f $MERKERINCR.tmp
if [ $fullbackup ]
then
rm -f $MERKERFULL.tmp
fi
mail -s "$TEXT $STARTSTRING gescheitert!" root <<-EOF
$0: $text ($STARTSTRING) gescheitert.
Genaueres steht in $LOGFILE.
Ende: `date +"%d.%m.%Y %H:%M"`
EOF
else
# tar scheint geklappt zu haben.
# Dann kann man jetzt die Merker für das letzte Backup
# (etc/backup/lastincr, $MERKERFULL) endgültig
# anlegen und das Inhaltsverzeichnis komprimieren:
gzip -9 $DIRFILE
mv $DIRFILE.gz $VERZEICHNIS_FUER_INHALTSVERZEICHNIS
chmod 640 $VERZEICHNIS_FUER_INHALTSVERZEICHNIS/$DIRFILE.gz
chown $DIRUSR:$DIRGRP \
$VERZEICHNIS_FUER_INHALTSVERZEICHNIS/$DIRFILE.gz
echo "Inhaltsverzeichnis steht in " \
$VERZEICHNIS_FUER_INHALTSVERZEICHNIS/$DIRFILE.gz >>$LOGFILE
mv $MERKERINCR.tmp $MERKERINCR
if [ $fullbackup ]
then
mv $MERKERFULL.tmp $MERKERFULL
fi
echo "ok, fertig ("`date +"%d.%m.%Y %H:%M"`")" >>$LOGFILE
echo "" >>$LOGFILE
mail -s "$text $STARTSTRING erfolgreich!" root <<-EOF
$0: $text ($STARTSTRING) erfolgreich.
Inhaltsverzeichnis steht in\
$VERZEICHNIS_FUER_INHALTSVERZEICHNIS/$DIRFILE.gz
Ende: `date +"%d.%m.%Y %H:%M"`
EOF
fi
# Ende.