Mein kleines backup Skript
7
Februar
“Moment, bevor ich die Config ändere, noch schnell ne Sicherungskopie von der original Datei machen. cp yum.conf yum.conf-201302 ... .. äh, welches Datum haben wir heute? So ein mist, na dann eben cp yum.conf yum.conf-$(date +%Y%... Großes M oder kleines m? Ich kann’s mir einfach nicht merken, außerdem zuviel Tipparbeit. Da muss was einfacheres her.”
.. und hier ist mein, zugegeben sehr einfaches aber wie ich finde recht nützliches bash-Skript für die Lösung des “Problems”.
Es hat den einfallsreichem Namen: backup
Meine Kollegen und ich verwendes es mittlerweile immer und überall. Auch in anderen Skripten, die mit Dateiänderungen arbeiten, kommt backup mit der -k Option zum Einsatz.
Kleines Beipiel
[root@myhost etc]# backup yum.conf
[root@myhost etc]# ls -l yum.conf*
-rw-r--r-- 1 root root 346 May 22 2012 yum.conf
-rw-r--r-- 1 root root 346 May 22 2012 yum.conf.20130207-084855
[root@myhost etc]# backup
usage: ./backup [-k <num> ] [-yv] file_to_backup [file_to_backup...]
options:
-k keep last backups and remove older files
-y assume 'yes' if backup a directory
-v verbose
[root@myhost etc]#
Features
- Sicherungskopien von mehreren Dateien und/oder Verzeichnissen erstellen
- Automatisches löschen alter Sicherungen mit der -k Option (nach dem Erstellen von Neuen).
Download und Installation
Einfach das Skript kopieren und irgendwo in den $PATH legen. Fertig.
Hier das backup Skript:
#!/bin/bash
#
# Creates a copy with timestamp of the file(s) given in argument.
# Optionally removes old copies
#
# by sascha.nowak@dfs.de
#
KEEPNUM=0 # 0 = disabled
function printhelp() {
echo "usage: $0 [-k <num>] [-yv] file_to_backup [file_to_backup...]" >&2
echo "options:" >&2
echo " -k keep last <num> backups and remove older files" >&2
echo " -y assume 'yes' if backup a directory" >&2
echo " -v verbose" >&2
exit 1
}
[ "$1" == "" ] && printhelp
while getopts ":k:yvh" opt
do
case $opt in
k)
[ ${OPTARG:0:1} = "=" ] && KEEPNUM=${OPTARG/=} || KEEPNUM=$OPTARG
;;
y)
YES="y"
;;
v)
VERBOSE="v"
;;
*)
printhelp
;;
esac
done
shift $(($OPTIND-1))
FILENAMES=$*
[[ $KEEPNUM == [0-9]* ]] || printhelp
# pre check
ERROR=0
for FILENAME in $FILENAMES; do
if [ ! -e $FILENAME ]; then
echo "file not found or unsupported filetype: $FILENAME" >&2
ERROR=1
fi
if [ -L $FILENAME ]; then
echo "file is a symlink: $FILENAME" >&2
ERROR=1
fi
if [ -d $FILENAME -a $ERROR != 1 ] ; then
if [ "$YES" != "y" ]; then
echo -n "Do you want to backup the whole directory $FILENAME? [Y/n] "
read YN
if [ "$YN" == 'n' ] ; then
echo OK, nothing backuped >&2
exit 1
else
YES=y
fi
fi
fi
done
if [ "$ERROR" == 1 ] ; then
echo 'Operation stopped because of previous errors. Nothing backuped!' >&2
exit 1
fi
# copy files
for FILENAME in $FILENAMES; do
# evtl / am Ende entfernen
FILENAME=$(echo $FILENAME | sed 's#/$##')
cp -pr$VERBOSE $FILENAME $FILENAME.`date +%Y%m%d-%H%M%S`
RETVAL=$?
if [ "$RETVAL" -ne 0 ] ; then
echo Copy error at file: $FILENAME >&2
exit $RETVAL
fi
done
# remove old files
if [ $KEEPNUM -gt 0 ]; then
for FILENAME in $FILENAMES; do
# evtl / am Ende entfernen
FILENAME=$(echo $FILENAME | sed 's#/$##')
I=0
for FILE in `ls -dr $FILENAME.????????-??????`; do
I=$(( $I + 1 ))
[ $I -gt $KEEPNUM ] && rm -rf$VERBOSE $FILE
done
done
fi
Für Ideen und Anmerkungen bin ich offen.

Super Script, vielen Dank…
Jo, git haben wir auch an ein paar Ecken im Einsatz, doch meist ist git doch zu overpowered…
Ansonsten gutes Howto auf deiner Seite!
Netter Schnippsel, gute Idee, aber beim Überfliegen fällt mir auf, dass wohl noch ein paar Hochkommata reinsollten, damit es keine Probleme beim Backup von Dateinamen mit Leerzeichen gibt.
Hm, hast Recht! Da wir das bis jetzt immer nur auf Servern für Configfiles verwendet haben und hier ja nie Leerstellen im Filename sind, ist es uns noch nicht aufgefallen. Werd ich bei gel. fixen. Thx!
Ich mag die Namen leserlicher: ich würde `date +%y-%m-%d_%H.%M` nutzen. So mache ich es zumindest mit automatisch erstellten Dateien, die sonst den gleichen Namen hätten. Und meist erstellt man ja auch nicht mehrere Backups pro Minute.
Aber das ist ja jedem seine Sache
Mit `date –iso-8601=minutes` bekommt man das Datum im ISO Format sogar mit Minuten und Zeitzone. Nicht ganz so einfach wie -I aber immerhin leichter zu merken als %Y-%m-%d-xyz. –iso-8601 versteht auch noch weitere Werte an stelle von minutes, so z.B. seconds oder “ns” um auf Sekunden und Nano(?) Sekunden die Zeit anzugeben.
date -I (-I = minus großes I wie Ida) erzeugt automatisch das aktuelle Datum im Format “YYYY-MM-DD”
Hey,
schöne Idee! Ein -d um ein Zielverzeichnis angeben zu können, wäre noch praktisch.
LG
Gute Idee! Werd mich mal drum kümmern! Thx!
Ich benutze etckeeper zusammen mit git: http://linpert.de/2012/06/02/etckeeper-und-git/