Seite 1 von 1

Migration von Verzeichnissen / robocopy -> subprocess

Verfasst: Dienstag 8. November 2011, 17:41
von VectorX
Moin Leute,
ich beschäftige mich schon seit einiger Zeit mit Python (bin aber noch immer etwas unbeholfen :? ).

Ich versuche größere Datenmengen von einem Windows Fileserver auf einen anderen zu bekommen (es geht hier um einige Terabyte). Ich habe nicht vor die alle auf einmal zu kopieren sondern Verzeichnis für Verzeichnis. Da ich die Dateiattribute auch kopieren muss kommt "shutil.copytree" nicht in Frage.

Ich habe mich nun entschlossen die Sache etwas allgemeiner anzugehen und robocopy über Python zu benutzen (das Problem welches sich hier zeigt hat allerdings eher etwas mit dem subprocess modul zu tun). Was ich erreichen möchte ist, dass ich den STDERR und den STDOUT in jeweils eigene Variablen schreiben kann und dann schauen kann wie der Fehlercode war und auch was genau falsch gelaufen ist. Ich rufe hierzu zunächst folgendes in der Kommandozeile (cmd.exe auf):
C:\Users\testuser>robocopy.exe unsinn

-------------------------------------------------------------------------------
ROBOCOPY :: Robustes Dateikopieren für Windows

-------------------------------------------------------------------------------

Gestartet: Tue Nov 08 17:21:03 2011

Quelle : C:\Users\testuser\unsinn\
Ziel -

Dateien : *.*

Optionen: *.* /COPY:DAT /R:1000000 /W:30

------------------------------------------------------------------------------

FEHLER: Es wurde kein Zielverzeichnis angegeben.

Einfache Syntax :: ROBOCOPY Quelle Ziel /MIR

Quelle :: Quellverzeichnis (Laufwerk:\Pfad oder \\Server\Freigabe\Pfad)
Ziel :: Zielverzeichnis (Laufwerk:\Pfad oder \\Server\Freigabe\Pfad)
/MIR :: Spiegelt eine vollständige Verzeichnisstruktur.

Weitere Informationen erhalten Sie über den Befehl "ROBOCOPY /?"


**** Der Befehl "/MIR" kann Dateien sowohl kopieren als auch LÖSCHEN.

C:\Users\testuser>robocopy.exe unsinn | ECHO %ERRORLEVEL%
16

Man kann hier sehen, dass das Kommando in den STDOUT jede menge Kram packt und als STDERR den Code 16 ausspuckt. Dies möchte ich nun in Python nachbauen. Hier möchte ich NICHTS in der Normalen Ausgabe von Python haben sondern alles in zwei Variablen schreiben.

Ich habe nun folgenden Code (vereinfacht):

Code: Alles auswählen

proc = subprocess.call('robocopy.exe unsinn',stderr = subprocess.PIPE,stdout = subprocess.PIPE)
print proc.communicate()
Hier bekomme ich folgendes raus:
AttributeError: 'int' object has no attribute 'communicate'
Gut die Sache ist soweit klar der hat eben nur den Fehlercode zurückgegeben. Wenn ich nun einfach:

Code: Alles auswählen

print subprocess.call('robocopy.exe unsinn',stderr = subprocess.PIPE,stdout = subprocess.PIPE)
verwende bekomme ich auch 16 ausgegeben. Aber wo bleibt der STDOUT?

Gut wenn man die Sache weiter verfolgt kommt man auf so eine Lösung:

Code: Alles auswählen

proc = subprocess.Popen('robocopy.exe unsinn',stderr = subprocess.STDOUT,stdout = subprocess.PIPE)
print proc.communicate()
Hier bekomme ich wie auch in der Doku erwähnt ein Tuple wieder ABER der zweite Wert (der STDERROR) in diesem Tuple ist None. Ich kann auch "stderr = subprocess.PIPE" versuchen, dann ist das Feld leer. Ich bekomme also entweder den Errorcode in eine Variable oder den Errorcode.

Die Frage ist also nun: Wie kann man es anstellen, dass subprocess beides in Variablen schreibt?

Ich versuche das hier schon einige Zeit und habe langsam das Gefühl ein krasses Brett vor dem Kopf zu haben. Ich habe vorher recht viel mit VBScript bzw. KiX gearbeitet (beides ja nun wirklich primitiv gegen python) aber hier war das Aufrufen von externen Befehlen und dann das Auslesen der Ausgabe nie ein echtes Problem.

So falls ihr euch durch meinen Text gekämpft habt bleibt mir nur noch zu sagen.
Vielen Dank und ich hoffe jemand hat eine Idee!

Re: Migration von Verzeichnissen / robocopy -> subprocess

Verfasst: Dienstag 8. November 2011, 17:52
von Dav1d
Ich versteh nicht was du brauchst, das hier?

Code: Alles auswählen

proc = subprocess.Popen(…, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
stdout, stder = proc.communicate()
print stdout
print 'Returncode:', proc.returncode

Re: Migration von Verzeichnissen / robocopy -> subprocess

Verfasst: Dienstag 8. November 2011, 18:02
von VectorX
Ja genau das!
Sagte ja... Brett vor dem Kopf. War auch schon kurz vor der Lösung.

Vielen Dank!

Re: Migration von Verzeichnissen / robocopy -> subprocess

Verfasst: Dienstag 8. November 2011, 18:47
von BlackJack
@VectorX: Etwas irreführend war IMHO Deine Pipe auf Kommendozeilenebene. Der %ERRORCODE% ist eine Umgebungsvariable und kommt eben nicht durch die Pipe. ``echo`` scheint die eigentlich Ausgabe von dem Prozess vor der Pipe einfach zu verschlucken.