Backup

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
F.Schmidt
User
Beiträge: 6
Registriert: Donnerstag 2. Februar 2017, 22:19

Hallo Python-Community,

ich beschäftige mich schon längere Zeit mit Python und kenne mich relativ gut aus, dennoch bin ich beim Basteln mit meinem Raspberry Pi auf ein paar Fragen gestoßen.

Meine Idee ist, dass der Raspi automatisch Backups macht. Diese sollen in einem Verzeichnis auf einem USB gespeichert werden. Soweit erstmal kein Problem. Ich möchte das ganze jetzt aber so ausbauen, dass die Verzeichnisse nach dem aktuellen Datum benannt werden. Also angenommen, ich würde heute (02.02.2017) ein Backup machen, dann soll das Verzeichnis 02-02-2017 auf meinem USB angelegt werden und das Backup da auch gespeichert werden. Wie lautet der Befehl, das aktuelle Datum als Ordnernamen zu verwenden?


Problem Nummer 2:
Damit der USB nicht irgendwann übervoll ist, sollen alle Backups, die älter als 14 Tage sind, automatisch wieder gelöscht werden. Das Datum ist ja in dem Ordnernamen vorhanden, man müsste es nur mit dem aktuellen Datum vergleichen. Wie dies jedoch umgesetzt wird, ist mir unklar.

Letztes Problem:
Das Skript, welches das Backup automatisch erstellt, wird automatisch, also mit jedem Reboot gestartet. Pro Tag soll allerdings nur ein Backup erstellt werden. Wie baut man dieses Feature ein?


Ich würde mich wahnsinnig über hilfreiche Antworten freuen, damit ich an meinem Raspi weiterarbeiten kann =)

LG
F.Schmidt
Benutzeravatar
framp
User
Beiträge: 52
Registriert: Samstag 9. Oktober 2010, 22:16
Wohnort: bei Stuttgart
Kontaktdaten:

Wenn es Dir nur ums Backup geht und Du nichts selbst in Python programmieren willst ist das vielleicht eine Alternative :)
BlackJack

@F.Schmidt: Backups sind fast wie Verschlüsselung: Man sollte es nicht selbst schreiben sondern etwas bewährtes verwenden. Also allerhöchstens bestehende Lösungen von Skripten aus verwenden, zum Beispiel weil man vorher Dienste anhalten muss oder für bestimmte Dienste andere Sicherungslösungen will oder braucht als für normale Dateien.
F.Schmidt
User
Beiträge: 6
Registriert: Donnerstag 2. Februar 2017, 22:19

Hallo,

gerne würde ich selbst etwas dazu skripten und bis jetzt funktioniert mein Entwurf ohne Probleme. Ich habe dennoch zwei (allgemeine) Fragen an euch:

1) Ich möchte einen Ordner mit dem aktuellen Datum als Namen erstellen. Wie kann ich dies umsetzen?

2) Wie kann ich das Erstelldatum eines Ordners und dessen Inhalts feststellen?


Vielen Dank im Voraus!
F.Schmidt
BlackJack

@F.Schmidt: Für Datumsangaben gibt's das `datetime`-Modul. Die Objekte kann man auch in Zeichenketten mit `format()` hinein formatieren und dabei auch die ganzen Formatoptionen verwenden.

Da gibt es auch eine Methode um Zeichenketten in `datetime.datetime`-Objekte zu parsen.

Für das Arbeiten mit Pfaden gibt es im `os`-Modul einen Haufen Funktionen.

Für das Format des Datums solltest Du übrigens 2017-02-03 verwenden, also Jahr, Monat, Tag, dann entspricht die ”alphabetische” Sortierung auch gleich der zeitlichen.
F.Schmidt
User
Beiträge: 6
Registriert: Donnerstag 2. Februar 2017, 22:19

Hallo,

das mit den Modulen ist mir klar. Dennoch ist mir der genaue Syntax für ein Programm, welches das Datum als Ordnernamen verwendet, schleierhaft.

Das Programm soll im Ordner /media/pi/INTENSO/Backup einen Unterordner mit dem Datum (als z.B. 2017-02-03, YYYY-MM-TT) erstellen.
Wie lautet dafür der Code?


LG
F.Schmidt
Benutzeravatar
framp
User
Beiträge: 52
Registriert: Samstag 9. Oktober 2010, 22:16
Wohnort: bei Stuttgart
Kontaktdaten:

Da mich das Thema interessiert hat habe ich mir das mal angesehen. Ein paar Mal googeln und fertig ist ... Ich frage mich warum Du die Antworten nicht gefunden hast :roll:

Anbei mein Ergebnis. Allerdings habe ich absichtlich aus didaktischen Gründen ein paar Fehler eingebaut 8)

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-

import os
import datetime

dt=datetime.now()						# -> https://docs.python.org/2/library/datetime.html

datePart=dt.strftime("%Y%w%d-%H%M%f") 	# -> https://docs.python.org/2/library/datet ... e-behavior

curDir = os.getcwd()
newPath = "%s%s" % ( curDir, datePart) 

if not os.path.exists(newpath):
    os.makedirs(newPath)
Zuletzt geändert von Anonymous am Freitag 3. Februar 2017, 22:41, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
F.Schmidt
User
Beiträge: 6
Registriert: Donnerstag 2. Februar 2017, 22:19

Hallo,

hier erstmal der verbesserte Code. Sollte ich einen Fehler übersehen haben, liegt es daran, dass ich den komplett ausgebesserten Code nicht schnell von Raspi kopiert habe, sondern erneut berichtigt habe. Es funktioniert jedenfalls sehr gut:

Code: Alles auswählen

    
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
     
    import os
    import datetime
     
    dt=datetime.now()            
     
    datePart=dt.strftime("%Y-%m-%d)
     
     os.chdir("/media/pi/INTENSO/Backup")
    curDir = os.getcwd()
    newPath = "%s%s" % ( curDir, datePart)
     
    if not os.path.exists(newPath):
        os.mkdir(newPath)
        

Jetzt muss ich euch aber noch einmal nerven. Und ich entschuldige mich im Voraus für die Frage ;)
Wenn ich diesen Code ausführe, wird im selben Verzeichnis, in dem auch Backup ist, ein neuer Ordner mit dem Namen Backupdatum erstellt.
Dies liegt, wenn ich den Code zumindest einigermaßen richtig verstanden habe, an den curDir-Befehl.

Wie muss ich diese paar Zeilen nun ändern, damit der Ordner Datum im Verzeichnis Backup gespeichert ist?

Danke für Eure Mühen,
F.Schmidt
Zuletzt geändert von Anonymous am Freitag 3. Februar 2017, 23:16, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@F.Schmidt: Das ist syntaktisch kein gültiges Python, wie kann das sehr gut funktionieren wenn es nicht einmal am Compiler vorbei kommt?

`os.chdir()` ist keine gute Idee. Damit verändert man globalen Zustand des Prozesses und das kann man höchstens ein einer Stelle machen, sonst wird es schnell unübersichtlich und man liest/schreibt am Ende an Stellen die gar nicht dafür vorgesehen waren. Man sollte besser die Pfade so angeben, dass man mit dem aktuellen Arbeitsverzeichnis des Prozesses kein Problem hat. Zumal es wenig sinnvoll ist erst in das Verzeichnis zu wechseln um dann doch mit einem absoluten Pfad dort hin zu arbeiten.
Benutzeravatar
framp
User
Beiträge: 52
Registriert: Samstag 9. Oktober 2010, 22:16
Wohnort: bei Stuttgart
Kontaktdaten:

<OT>
@BlackJack : Du hast meinen Code der mit \[code\] markiert war geändert. Macht Sinn. Sieht besser aus. Welche Tags hast Du nun eingefügt? ... nur damit ich das nächste Mal gleich die richtigen Tags benutze :D
</OT>
F.Schmidt
User
Beiträge: 6
Registriert: Donnerstag 2. Februar 2017, 22:19

@F.Schmidt: Das ist syntaktisch kein gültiges Python, wie kann das sehr gut funktionieren wenn es nicht einmal am Compiler vorbei kommt?
Wie ich bereits erwähnte, bei mir geht alles fehlerfrei und ist problemlos ausführbar:

Code: Alles auswählen

import lcddriver
import os
import datetime
import time

display = lcddriver.lcd()

os.chdir("/media/pi/INTENSO/Backup")

newPath = str(datePart)

if not os.path.exists(newPath):
    os.mkdir(newPath)
    shutil.copytree("/home" , "[b][i]HierFehltDerSyntax[/i][/b]")

else:
    display.lcd_clear()
    display.lcd_display_string("Backup already" , 1)
    display.lcd_display_string("created today!" , 2)
    time.sleep(10)

Mir ist mttlerweile nur noch nicht ganz klar, wie ich in diesen neuen Ordner ein Verzeichnis kopieren kann.

Code: Alles auswählen

shutil.copytree("/home" , "/media/pi/INTENSO/Backup")
Soweit funktioniert das natürlich, aber statt "/media/pi/INTENSO/Backup" sollte es in "/media/pi/INTENSO/Backup/angelegterOrdner kopiert werden.
Wie erreiche ich das?


LG
F.Schmidt

//Edit:
Lasst euch von den ganzen LCD-Befehlen nicht ablenken. Wenn die bei euch einen Syntaxfehler ausgeben, ist das logisch, da euch bestimmte Libraries dafür fehlen. Da diese für meine Frage nicht relevant sind, könnt ihr sie euch einfach wegdenken ;)
BlackJack

@F.Schmidt: Syntax ist nicht das was Du denkst. Wenn wir einen Syntaxfehler bekommen dann liegt das nicht an fehlenden Bibliotheken sondern das der Quelltext grundsätzlich nicht der Grammatik für Python entspricht. Dann wird der gar nicht erst kompiliert, läuft also gar nicht. Eine fehlende Bibliothek führt zum einem Laufzeitfehler.

Auch mit den Bibliotheken wird das jetzt gezeigte nicht fehlerfrei und problemlos laufen. Das geht bis Zeile 10 wo dann ein `NameError` ausgelöst wird weil `datePart` nicht definiert ist.

Du hast da immer noch `os.chdir()` drin. Lass das sein.

Erstelle eine Zeichenkette die den gewünschten Pfad enthält und binde die an einen Namen wenn der Wert an mehr als einer Stelle benötigt wird.
F.Schmidt
User
Beiträge: 6
Registriert: Donnerstag 2. Februar 2017, 22:19

Code: Alles auswählen

import lcddriver
import os
import shutil
import datetime
import time

display = lcddriver.lcd()



# https://docs.python.org/2/library/datetime.html
dt=datetime.datetime.now()    

# https://docs.python.org/2/library/datet ... e-behavior
datePart=dt.strftime("%Y-%m-%d")


os.chdir("/media/pi/INTENSO/Backup")
# curDir = os.getcwd()
# newPath = "%s%s" % (curDir, datePart)
newPath = str(datePart)

if not os.path.exists(newPath):
    os.mkdir(newPath)
    shutil.copytree("/home" , "/media/pi/INTENSO/Backup"+newPath)

else:
    display.lcd_clear()
    display.lcd_display_string("Backup already" , 1)
    display.lcd_display_string("created today!" , 2)
    time.sleep(10)
So...das ist der momentane Code. Habe vergessen einen Teil zu kopieren. ;)

Das os.chdir() soll weg. Wie genau binde ich den Pfadnamen so ein, dass genau dort das Verzeichnis erstellt wird?
Und wie lautet der shutil.copytree-Befehl, damit das Verzeichnis /home in das neu erstellte Verzeichnis kopiert wird?

LG
F.Schmidt
nezzcarth
User
Beiträge: 1632
Registriert: Samstag 16. April 2011, 12:47

Um BlackJacks Einwand vom Anfang des Threads noch mal aufzugreifen: Das Verfahren, das du beschreibst, wird so ähnlich für "DIY-Backuplösungen" zwar schon ab und an mal verwendet, aber mit dem großen Unterschied, dass die Kernfunktionalität dann von zum Beispiel von rsync oder duplicity erledigt wird und für die Steuerung meist ein einfaches Shell-Skript, das per (Ana)cron aufgerufen wird, zum Einsatz kommt. Es gibt auch Backup-Lösungen, die in Python geschrieben sind (zum Beispiel BorgBackup); das sind aber deutlich mehr als ein paar Zeilen…
Antworten