Benötige Hilfe beim Backup-Skript

  • Hey alle zusammen,

    ich versuche mich gerade am erstellen eines scriptes und stecke irgendwie in einer sackgasse :(

    folgendes ist mein ziel:

    ich möchte bald in meinem htpc ein ssd laufwerk verbauen um strom zusparen und den lärm der "normalen" festplatten zu vermeiden.

    leider sind die dinger noch sehr teuer und mehr als 64gb werd ich mir da eh nicht leisten können.

    diese sind aber mit tv aufnahmen (gerade bei hdtv) sehr schneller gefüllt und daher muss das ganze regelmäßig auf eine herkömmliche festplatte gesichert werden.

    vom prinzip her wollte ich dafür ein skript erstellen und dieses vor jedem herunterfahren ausführen - folgenden "plan" hab ich mir dazu überlegt. leider mangelt es an der praktischen umsetzung!

    1. Schritt: prüfen wieviel freier speicherplatz noch auf der ssd platte zur verfügung steht.

    bei >15 GB soll sich das skript einfach wieder beenden

    2. Schritt: prüfen ob die datentank festplatte überhaupt angeschlossen ist (wird meistens nicht der fall sein)

    -> wenn nein: Statusmeldung abgeben

    3. Schritt:

    Ordner Aufnahmen auf der ssd in den ordner Aufnahmen auf der Datenfestplatte kopieren

    4. Schritt:

    Eine Art Prüfsumme zwischen den kopierten Datein um sicherzustellen, dass alles funktioniert hat.

    5. Schritt:

    Inhalt des Aufnahme ordners auf der ssd löschen.

    6. Schritt

    PC herunterfahren (schritt fehlt in meinem entwurf, aber das bekomm ich schon hin)

    soweit bin ich gekommen:

    [autoit]


    #cs
    Titel: Aufnahmesicherung
    Autor: Nuts
    Beschreibung: Backup von SSD auf Datentank
    #ce
    ;Definition der Variablen
    dim $titel
    $titel = "Backup-Skript"
    dim $quelle
    $quelle = "C:\Dokumente und Einstellungen\Nussman\Eigene Dateien\test-backup2"
    dim $ziel
    $ziel = "H:\test"
    dim $ziel2
    $ziel2 = "D:\test-backup"
    dim $freierSpeicher
    $freierSpeicher = DriveSpaceFree( "D:\" )

    [/autoit][autoit][/autoit][autoit]

    ;prüft den freien Speicherplatz
    MsgBox(4096, "Free space on D:\", $freierSpeicher & " MB")
    ;prüft ob Zielverzeichnis existiert
    if FileExists($ziel2) Then
    ;Kopiert Quelle -> Ziel
    dircopy ( $quelle, $ziel2 , 0 )
    ;kurz warten
    sleep (1000)
    ;datein in quelle löschen
    FileDelete ($quelle)
    else
    MsgBox(64, $titel, "Zielverzeichnis nicht gefunden!" , 5)
    EndIf

    [/autoit]

    die variable "ziel" ist ein usb stick zum überprüfen ob das zielverzeichnis existiert und wird eigentlich nicht benötigt.

    meine probleme sind auf aus der info wieviel speicherplatz noch zur verfügung steht eine if then/else schleife einzuleiten um eben das backup zu starten oder den pc gleich herunterzufahren.

    und bei schritt 4, also der prüfsumme, fehlt mir komplett der ansatz wie das gehen soll.

    der datentank wird mit der zeit natürlich immer "voller" also kann ich nicht einfach abgleichen ob quellverzeichnis und zielverzeichnis gleich groß sind.

    irgendeine überprüfung, ob das kopieren erfolgreich war, wäre aber schon super, da sonst meine aufnahmen im ernstfall im quellverzeichnis gelöscht werden und im zielverzeichnis nur unvollständig oder fehlerhaft vorhanden sind! ist sowas mit autoit möglich?

    ansonsten funktioniert das ganze eigentlich wie es soll :D

    was noch interessant wäre: muss ich nach "dircopy" eine art wartefunktion einbauen? immerhin könnte es passieren, dass ~15gb kopiert werden müssen und das dauert schon etwas länger. bei meinen tests (nur mit ~1gb großen dateien) war dies nicht nötig - also das skript hat erst weitergemacht nachdem die datein kopiert wurden!

    vielen dank schonmal für die antworten.

    gruß nuts

    • Offizieller Beitrag

    Eine Pause nach DirCopy() ist nicht nötig.

    Ein vollständiges überprüfen der Dateien kostet Zeit und zwar fast genau so viel, wie die Zeit zum kopieren (lesen geht meist schneller als schreiben, deshalb: fast). Das ist Dir klar?

    Möglich wäre es, wenn Du nach dem kopieren von den Dateien (Quell- und Zieldateien) MD5-Checksummen erstellst und diese miteinander vergleichst. Du könntest auch beide in den Speicher einlesen (FileRead) und miteinander vergleichen (bei GB-großen Dateien aber nicht zu empfehlen).

    Zu Deinem bisherigen Script: Du "prüfst" (zeigst ihn an) den freien Speicher auf D:, sollte das nicht eher C: (Quelle) sein (Schritt 1)?

    • Offizieller Beitrag

    Dateigrößenvergleich dürfte doch in aller Regel reichen, oder?
    Dann ginge z.B. DirGetSize mit dem Flag, das auf Unterordner scannt :).

    Und mal ein Lob für deine Herangehensweise! Sauber und algorithmisch/schrittweise das Problem formuliert, so kann man das dann optimal in Code umsetzen :).

    Bisschen Code noch für dich für die Platzprüfung:

    [autoit]

    $freierSpeicher = DriveSpaceFree( "D:\" )

    [/autoit][autoit][/autoit][autoit]

    ;prüft den freien Speicherplatz
    If $freierSpeicher > 15*1024 Then Exit ; bricht ab, wenn mehr als 15 GB frei sind, ansonsten einfach weiter in der nächsten Zeile

    [/autoit]

    peethebee

  • hehe super das abfragen des speicherplatzes läuft schonmal, danke :thumbup:

    die prüfsummen geschichte verstehe ich noch nicht so ganz ?(

    es gibt im prinzip im quell ordner und im ziel ordner keine unterordner sondern nur die aufnahme dateien.

    um die größe der ordner zu vergleichen müsste ich doch so vorgehen:

    Quellegröße (A) + Zielgröße (B) vor dem kopieren abfragen

    und dann B nach dem kopieren abfragen und diesen mit den gesammelten Daten ( B - A) vor dem kopieren vergleichen.

    klingt auch recht kompliziert für jemanden, der sein erstes skript bastelt ;(

    über md5 checksummen muss ich erstmal etwas googeln. sagt mir nichts und in der hilfe finde ich leider auch keinen ansatz!

    wie lange das ganze dauert wäre im eigentlich egal, da die ganze aktion erst nach dem ins bett gehen startet ;)

    Einmal editiert, zuletzt von nuts (19. Juli 2008 um 15:29)

    • Offizieller Beitrag

    Du hast es dir wieder richtig formuliert:

    Zitat

    Quellegröße (A) + Zielgröße (B) vor dem kopieren abfragen

    und dann B nach dem kopieren abfragen und diesen mit dem gesammelten Daten ( B - A) vor dem kopieren vergleichen.

    Einfach die Größen mit DirGetSize in Variablen packen und dann mit einer If-Abfrage testen. Wenn alles passt, dann die Quelldateien wie gehabt löschen, sonst da lassen, dann weißt du frühs, dass etwas schiefgegangen ist (kannst auch noch Log-Eintrag machen mit _FileWriteLog) :).

    Viel Erfolg dabei,
    peethebee

  • ah ich denke ich habs geschafft:

    Spoiler anzeigen
    [autoit]

    #cs
    Titel: Aufnahmesicherung
    Autor: Michael Wolf
    Beschreibung: Backup von SSD auf Datentank
    #ce

    [/autoit] [autoit][/autoit] [autoit]

    ;Definition der Variablen
    dim $titel
    $titel = "Backup-Skript"
    dim $quelle
    $quelle = "C:\Dokumente und Einstellungen\Nussman\Eigene Dateien\test-backup2"
    dim $ziel
    $ziel = "H:\test"
    dim $ziel2
    $ziel2 = "D:\test-backup"
    dim $freierSpeicher
    dim $sizequelle1
    dim $sizequelle2
    dim $sizeziel1
    dim $sizeziel2
    $freierSpeicher = DriveSpaceFree( "D:\" )

    [/autoit] [autoit][/autoit] [autoit]

    ;prüft den freien Speicherplatz
    If $freierSpeicher > 15*1024 Then
    MsgBox (64, $titel, "Mehr als 15 GB verfügbar!", 5)
    Exit ; bricht ab, wenn mehr als 15 GB frei sind, ansonsten einfach weiter in der nächsten Zeile

    [/autoit] [autoit][/autoit] [autoit]

    elseif $freierSpeicher < 15*1024 Then
    ;prüft ob Zielverzeichnis existiert
    if FileExists($ziel2) Then

    [/autoit] [autoit][/autoit] [autoit]

    ; 1 Schritt: Check des Kopiervorgangs
    $sizequelle1 = DirGetSize ($quelle)
    $sizeziel1 = DirGetSize ($ziel2)

    [/autoit] [autoit][/autoit] [autoit]

    ;Kopiert Quelle -> Ziel
    dircopy ( $quelle, $ziel2 , 1 )

    [/autoit] [autoit][/autoit] [autoit]

    ; 2 Schritt: Check des Kopiervorgangs
    $sizequelle2 = DirGetSize ($quelle)
    $sizeziel2 = DirGetSize ($ziel2)

    [/autoit] [autoit][/autoit] [autoit]

    if $sizeziel2 = $sizequelle1 + $sizeziel1 Then
    FileDelete ($quelle)
    Else
    MsgBox(64, $titel, "Sicherung fehlgeschlagen" , 5)

    [/autoit] [autoit][/autoit] [autoit]

    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ;kurz warten
    sleep (1000)

    [/autoit] [autoit][/autoit] [autoit]

    ;datein in quelle löschen
    FileDelete ($quelle)

    [/autoit] [autoit][/autoit] [autoit]

    else
    MsgBox(64, $titel, "Zielverzeichnis nicht gefunden!" , 5)
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    EndIf

    [/autoit]

    fehlt nurnoch ein logfile wenn das kopieren fehlgeschlagen ist. (damit kämpfe ich grad)

    sieht sonst jemand grobe bugs? meine tests waren alle erfolgreich - aber mir fällt nix geeignetes ein um das fehlgeschlagene kopieren zu simulieren! jemand dafür ne idee?

    ajo: dircopy funktioniert nur mit dem flag 1 (was auch nicht schlimm ist)

    laut hilfe sollte es aber auch mit flag 0 funktionieren und einfach nix überschreiben?

    • Offizieller Beitrag

    Hallo!

    [autoit]

    elseif $freierSpeicher < 15*1024 Then

    [/autoit]


    Das ist unnötig :). Wenn oben der Teil Exit ausgeführt wurde, dann ist das Skript sowieso zu Ende.
    Also reicht hier statt dessen

    [autoit]

    EndIf

    [/autoit]

    Außerdem behebt das den "Bug", dass bei genau 15 GB frei weder MsgBox käme noch kopiert würde ;).

    Herunterfahren kannst du dann ganz unten mit Shotdown (siehe Hilfe).
    Wenn du dann MsgBox jeweils durch _FileWriteLog ersetzt, dann läuft es schön abends und schont deine Stromrechnung ;).

    peethebee