staging.inyokaproject.org

Fehlerhaftes Backupscript

Status: Ungelöst | Ubuntu-Version: Server 16.04 (Xenial Xerus)
Antworten |

gnude

Avatar von gnude

Anmeldungsdatum:
11. Juli 2014

Beiträge: 843

Hallo, vor einiger Zeit hat mir ein Bekannter mal ein kleines Backupscript geschrieben das unter älteren Debian Versionen (Debian 5,6,7) tadellos funktioniert hat. Auf Ubuntu 16.04 sichert es auch so wie es soll, entfernt aber nicht die Verzeichnisse nach der Anzahl X (es sollen x Verzeichnisse vorgehalten werden, die ältesten werden gelöscht).

Kann mir jemand nen Tipp geben?

1
2
3
4
5
6
7
8
9
#!/bin/sh
DATE=$(date +%Y%m%d)
SOURCE="/Netzwerklaufwerk"
DEST="/daten/Netzwerkbackup/"
DESTDATE="${DEST}/${DATE}"
eval mkdir -p ${DESTDATE}
eval cp -af ${SOURCE} ${DESTDATE}
X=15
eval cd ${DEST} && ${SAVE} rm -rf $(which ls | sort | head -n -${X})

Moderiert von redknight:

Ins am wenigsten unpassende Forum verschoben.

kB Team-Icon

Supporter, Wikiteam
Avatar von kB

Anmeldungsdatum:
4. Oktober 2007

Beiträge: 9837

gnude schrieb:

[…]

1
2
[…]
eval cd ${DEST} && ${SAVE} rm -rf $(which ls | sort | head -n -${X})

Ich sehe 3 Fehler in der letzten Zeile:

  • Die Variable SAVE wird im Skript nicht definiert. Was liefert:

    echo "SAVE=$SAVE!"
  • which ls liefert nur den vollständigen Namen von ls, führt ls aber nicht aus. Möglicherweise funktioniert (Vorsicht, das löscht in Kombination mit rm!) $($( which ls ) | sort | head -n -${X}) besser.

  • Die Ausgabe von ls skriptet man nicht! Es gibt hier zuviele mögliche Fehlerquellen.

Wenn Du in einem Skript die sehr gefährlichen Befehle eval und rm verwendest, solltest Du auf jeden Fall im Shebang angeben, welche der möglichen Shells (dash, bash, …) Du wirklich verwenden möchtest. Die einzelnen Shells verhalten sich unterschiedlich und #!/bin/sh kann kontextabhängig unterschiedliche Ergebnisse liefern!

PS: eval is evil!

Seebär

Avatar von Seebär

Anmeldungsdatum:
2. Mai 2009

Beiträge: 833

Und falsch ist es obendrein: hier werden nicht "X vorgehalten", sondern X gelöscht. Der

1
ls | sort | head -n $X

soll wohl so gedacht sein die ersten X (hier 15) Dateien / Verzeichnisse zu liefern und dann zu löschen. Da hier "zufällig" nach dem Muster yyyymmdd die Backup-Folder erstellt werden sind das die 15 "ältesten" Folder (da lexikographisch aufsteigend), welche dann ohne Gnade mit rm -rf gelöscht werden. Bedeutet:

  • wenn mal was anderes dazwischen steht geht es in die Hose

  • du darfst das Skript erst ab der 16. Sicherung einsetzen, sonst löschst du (vmtl.) die aktuelle Sicherung gerade wieder

Beschäftige dich besser mit sauberen Lösungen, BorgBackup wäre eine.

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Dein Bekannter hat Dir dummerweise 3 Sorten Bömbchen ins Skript eingebaut:

  1. die ganzen eval - nicht nur überflüssig, sondern ein Sicherheitsrisiko. (haben die Anderen ja auch schon drauf hingewiesen)

  2. die Ausgabe von ls parsen ist gefährlich. → Ein No-Go, das man definitiv nicht braucht.

  3. Dann noch eindeutiger Shebang, eigene Variablen $klein geschrieben, und sauber "quoten", und alles ist gut

Also, das Ganze noch einmal, jetzt ohne Bömbchen: (so eine Schleife für den Zeitvergleich hatte ich letztens hier schonmal)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/bin/bash

heute=$(date +%Y%m%d)
source="/Netzwerklaufwerk"
dest=/daten/Netzwerkbackup
destheute="$dest/$heute"
x=15

mkdir -p "$destheute"
cp -af "$source" "$destheute"

while true; do                                              # Außenschleife: wiederholen bis Abbruch
    i=0
    for d in "$dest"/*/; do                                   # ältestes Verzeichnis finden
        if [ "$d" -ot "$aelteste" -o ! "$aelteste" ]; then    #
            aelteste="$d"                                     #
        fi                                                    #
        ((i++))                                               # (dabei mitzählen)
    done                                                      #
    if [ $i -gt $x ]; then                                  # ggf. überflüssige löschen
        rm -r "$aelteste"
        aelteste=""
    else
        break
    fi
done

Bitte schreib vor die Zeile 21 zunächst ein echo davor, zum Testen !
Erst wenn alles einwandfrei läuft, dann kannst Du es wieder weg machen.

LG,

track

frostschutz

Avatar von frostschutz

Anmeldungsdatum:
18. November 2010

Beiträge: 7795

die Ausgabe von ls parsen ist gefährlich. → Ein No-Go, das man definitiv nicht braucht.

Das gleiche könnte man über die Verwendung von rm in "Backupscripten" sagen.

Eigentlich ist das ein Löschscript, und es ist nicht unmöglich und wäre nicht das erste Mal, daß gute Backups gelöscht werden ohne daß neue Backups existieren. Keine Fehlerprüfung, windige Logik, ...

Wenn es nicht brennt, dann lieber mv statt rm in ein Verzeichnis zur Sichtung und das von Zeit zu Zeit händisch ausputzen, nachdem man sich vergewissert hat, daß man das alte Zeug wirklich nicht mehr braucht.

Wenn Speicherplatz knapp ist sollte man das eh anders aufziehen.

Antworten |