Mein kleines backup Skript

“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.

11 Responses to Mein kleines backup Skript

  1. Sascha

    Jo, git haben wir auch an ein paar Ecken im Einsatz, doch meist ist git doch zu overpowered…
    Ansonsten gutes Howto auf deiner Seite!

  2. 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.

    • Sascha

      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!

  3. Pirad

    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 ;)

  4. Ben

    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.

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>