Seite 1 von 1
Suche Hilfe bei ersten Gehversuchen
Verfasst: Dienstag 26. August 2008, 17:11
von frank2342
Hallo zusammen,
ich starte gerade meine ersten Gehversuche mit Python. Dabei soll am Ende ein kleines Backupscript rauskommen.
Das Ganze sieht im Moment folgendermaßen aus:
Code: Alles auswählen
#!/usr/bin/python
#############
# Functions #
#############
import os
import os.path
import shutil
import time
import subprocess
def GET_TIME():
return time.strftime("%d.%m.%Y %H:%M:%S", time.localtime())
def DO_RDIFF(SOURCE, TARGET, EXCLUDE, LOGFILE):
LOG = file(LOGFILE, 'a')
LOG.write(GET_TIME() + " " + SOURCE + "\n")
if os.path.isdir(TARGET) == False:
os.system("mkdir -p " + TARGET)
LOG.write(GET_TIME() + " " + TARGET + " created \n")
CMD = "rdiff-backup --print-statistics " + EXCLUDE + " " + SOURCE + " " + TARGET
subprocess.call(CMD, stdout=LOG, stderr=LOG)
LOG.write(GET_TIME() + " done \n\n")
LOG.close()
#############
# WebFolder #
#############
SOURCE = "/var/www/"
TARGET = "/var/backups/vserver/www/"
LOGFILE = "/var/backups/vserver/backup.log"
EXCLUDE = ""
EXCLUDE = EXCLUDE + " --exclude **backups"
EXCLUDE = EXCLUDE + " --exclude ***.log"
EXCLUDE = EXCLUDE + " --exclude **phptmp"
EXCLUDE = EXCLUDE + " --exclude ***.tmp"
DO_RDIFF(SOURCE, TARGET, EXCLUDE, LOGFILE)
Starte ich das Script erhalte ich folgende Fehlermeldung:
Code: Alles auswählen
Traceback (most recent call last):
File "./rbackup2.py", line 44, in ?
DO_RDIFF(SOURCE, TARGET, EXCLUDE, LOGFILE)
File "./rbackup2.py", line 26, in DO_RDIFF
subprocess.call(CMD, stdout=LOG, stderr=LOG)
File "/usr/lib/python2.4/subprocess.py", line 413, in call
return Popen(*args, **kwargs).wait()
File "/usr/lib/python2.4/subprocess.py", line 543, in __init__
errread, errwrite)
File "/usr/lib/python2.4/subprocess.py", line 975, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
Der Befehl in "CMD" wird auf jeden Fall richtig zusammengesetzt. Lasse ich mir den Befehl mit print ausgeben und führe den direkt in der Shell aus funktioniert alles wie gewollt. Irgendwie hakt es an "subprocess.call". Mit meinem Latein bin ich vorerst am Ende. Dazu fehlt mir die Erfahrung in Python. Ihr könnt mir aber sicher ganz schnell auf die Sprünge helfen wo mein Fehler liegt.
Viele Grüße
Frank
Verfasst: Dienstag 26. August 2008, 17:18
von lunar
subprocess.call nimmt eine Liste als erstes Argument entgegen. Im Übrigen kannst du den os.system Aufruf bei der Gelegenheit auch gerade ersetzen.
Desweiteren ist es im Bezug auf die Namensgebung in Python üblich, die Regeln des Styleguides PEP 8 einzuhalten. Danach sind Großbuchstaben für Konstanten reserviert, Funktionen und "normale" Namen werden klein geschrieben.
Außerdem solltest du den Aufruf von "file" mit entsprechender Ausnahmebehandlung versehen und "file" vielleicht auch gleich durch "open" ersetzen.
Verfasst: Dienstag 26. August 2008, 17:42
von frank2342
lunar hat geschrieben:subprocess.call nimmt eine Liste als erstes Argument entgegen. Im Übrigen kannst du den os.system Aufruf bei der Gelegenheit auch gerade ersetzen.
ich habe aus
gemacht. Jetzt bricht das Script allerdings schon an der Stelle ab:
Code: Alles auswählen
Traceback (most recent call last):
File "./rbackup2.py", line 44, in ?
do_rdiff(source, target, exclude, logfile)
File "./rbackup2.py", line 22, in do_rdiff
subprocess.call("mkdir", "-p " + target)
File "/usr/lib/python2.4/subprocess.py", line 413, in call
return Popen(*args, **kwargs).wait()
File "/usr/lib/python2.4/subprocess.py", line 494, in __init__
raise TypeError("bufsize must be an integer")
TypeError: bufsize must be an integer
lunar hat geschrieben:Desweiteren ist es im Bezug auf die Namensgebung in Python üblich, die Regeln des Styleguides PEP 8 einzuhalten. Danach sind Großbuchstaben für Konstanten reserviert, Funktionen und "normale" Namen werden klein geschrieben.
OK, so kenne ich es von PHP auch. Hatte nur hier zum lernen Großbuchstaben verwendet.
lunar hat geschrieben:Außerdem solltest du den Aufruf von "file" mit entsprechender Ausnahmebehandlung versehen und "file" vielleicht auch gleich durch "open" ersetzen.
Sobald ich die basics drauf habe baue ich das Script aus.
Verfasst: Dienstag 26. August 2008, 17:49
von lunar
Was genau hast du an "subprocess.call nimmt eine Liste als erstes Argument entgegen" nicht verstanden?
Verfasst: Dienstag 26. August 2008, 18:03
von frank2342
lunar hat geschrieben:Was genau hast du an "subprocess.call nimmt eine Liste als erstes Argument entgegen" nicht verstanden?
Sorry, aber wenn du so fragst wahrscheinlich alles.
damit funktioniert jetzt erstmal das anlegen des Verzeichnis wieder.
Also wenn ich das jetzt richtig verstanden habe, MUSS das erste Argument eine Liste sein. Auch wenn die Liste mal nur einen einzigen Wert hat.
Das gleiche habe ich versucht auf den nächsten Aufruf anzuwenden
Code: Alles auswählen
cmd = ["rdiff-backup", "--print-statistics", exclude, source, target]
subprocess.call(cmd, stdout=log, stderr=log)
Ohne Erfolg. Im Log-File steht:
Code: Alles auswählen
Fatal Error: Switches missing or wrong number of arguments
See the rdiff-backup manual page for more information.
Verfasst: Dienstag 26. August 2008, 18:13
von lunar
frank2342 hat geschrieben:damit funktioniert jetzt erstmal das anlegen des Verzeichnis wieder.
Btw, "os.mkdir" und "os.makedirs" existieren.
Also wenn ich das jetzt richtig verstanden habe, MUSS das erste Argument eine Liste sein. Auch wenn die Liste mal nur einen einzigen Wert hat.
Ja.
Das gleiche habe ich versucht auf den nächsten Aufruf anzuwenden
Code: Alles auswählen
cmd = ["rdiff-backup", "--print-statistics", exclude, source, target]
subprocess.call(cmd, stdout=log, stderr=log)
Ohne Erfolg. Im Log-File steht:
Code: Alles auswählen
Fatal Error: Switches missing or wrong number of arguments
See the rdiff-backup manual page for more information.
Wenn dich das wundert, dann lass dir deine "cmd"-Liste mal mit "print" ausgeben. Das ist nämlich keine richtige Argumentliste.
Verfasst: Dienstag 26. August 2008, 18:23
von frank2342
lunar hat geschrieben:
Wenn dich das wundert, dann lass dir deine "cmd"-Liste mal mit "print" ausgeben. Das ist nämlich keine richtige Argumentliste.
Code: Alles auswählen
['mkdir', '-p', '/var/backups/vserver/www/']
['rdiff-backup', '--print-statistics', ' --exclude **backups', '/var/www/', '/var/backups/vserver/www/']
der einzige Unterschied den ich feststellen kann ist die Länge der Liste. Verkürze ich die Liste auch auf drei Werte:
Code: Alles auswählen
cmd = ["rdiff-backup", "--print-statistics" + exclude, source + " " + target]
Code: Alles auswählen
['rdiff-backup', '--print-statistics --exclude **backups', '/var/www/ /var/backups/vserver/www/']
bekomme ich wieder die Fehlermeldung:
Code: Alles auswählen
Fatal Error: Bad commandline options: option --print-statistics --exclude **backups not recognized
See the rdiff-backup manual page for more information.
Verfasst: Dienstag 26. August 2008, 18:31
von frank2342
ich verstehe es einfach nicht. So funktioniert es:
Aber wie bekomme ich die zusätzlich Optionen --print-statistics und die excludes da noch mit rein?
Verfasst: Dienstag 26. August 2008, 18:35
von Rebecca
Probier's mal so:
Code: Alles auswählen
['rdiff-backup', '--print-statistics', '--exclude', '**backups', '/var/www/', '/var/backups/vserver/www/']
Verfasst: Dienstag 26. August 2008, 18:39
von BlackJack
Schau Dir die Fehlermeldung noch einmal *genau* an: `rdiff-backup` meckert, dass es die Option (einzahl!) '--print-statistics --exclude **backups' nicht kennt. Was Du da machst entspricht in der Shell einem:
Code: Alles auswählen
rdiff-backup '--print-statistics --exclude **backups' '/var/www/ /var/backups/vserver/www/'
Du musst die einzelnen Argumente auch wirklich *einzeln* in der Liste aufführen.
Code: Alles auswählen
['rdiff-backup', '--print-statistics', '--exclude', '**backups', '/var/www/', '/var/backups/vserver/www/']
Edit: Mist zu langsam.

Verfasst: Dienstag 26. August 2008, 18:41
von frank2342
Aaahhhh, jetzt (nachdem ich noch das Leerzeichen vor --exclude entfernt habe) funktioniert es.
Code: Alles auswählen
cmd = ['rdiff-backup', '--print-statistics', '--exclude', '**backups', '/var/www/', '/var/backups/vserver/www/']
Als kurze Zusammenfassung:
subprocess.call verlangt als erstes IMMER eine Liste. In dieser Liste muss JEDE EINZELNE OPTION als Wert enthalten sein. Man kann also keine Optionen zusammenfassen und darf keine Leerzeichen verwenden. Richtig so?
Verfasst: Dienstag 26. August 2008, 19:07
von lunar
Ja.
Verfasst: Mittwoch 27. August 2008, 07:38
von frank2342
Super, Vielen Dank an alle.