Python - subprocess - stdout in DAtei?
Hallo.
Ich schreibe in Python gerade ein Backup Script wobei ich rsync über einen subprocess aufrufe.
Ich möchte hier die Ausgabe gleichzeitig im Terminal anzeigen lassen und in eine Datei schreiben.
Ist das möglich?
Ich würde das ungefähr so übergeben:
backup_process = subprocess.Popen(rsync_liste), stdout=subprocess.PIPE, stderr=subprocess.PIPE
stdout, stderr = backup_process.communicate()
print(stdout.decode('utf-8').split('\n'))
print(stdout.decode('utf-8').split('\n'))
stdout_datei = open('stdout_datei.txt', 'w')
Aber dann werden die Schritte nacheinander ausgeführt (meines Wissens zumindest)
Habe die Befürchtung, dass wenn das Backup dann recht lang ist, dass dann nicht alles ausgegeben bzw. gespeichert wird.
Wie könnte man das sinnvoller machen?
Hab die Frage gestern schonmal gestellt und auch wahrscheinlich eine gute Antwort bekommen, aber ich bekomme es trotzdem nicht hin. Ich schaffe es nicht das logging mit meinem Backup Script zu kombinieren.
Weiß nicht ob man die gestrige Antwort sehen kann deshalb schreibe ich sie grob mal her: (bzw. den Code der Antwort)
import logging
logger = [logging.getLogger(name), logging.getLogger(name2)]
fh = logging.FileHandler(filename)
fh.setLevel(logging.DEBUG)
sh = logging.StreamHandler()
sh.setLevel(logging.DEBUG)
formatter = logging.Formatter('[%(asctime)s] %(levelname)-2s %(name)-4s \n%(message)s', "%d.%m.%y %H:%M:%S")
sh.setFormatter(formatter)
fh.setFormatter(formatter)
for log in logger:
log.addHandler(fh)
log.addHandler(sh)
log.setLevel(logging.DEBUG)
Ich verstehe leider jetzt nicht wie ich in dem oben gezeigten code meinen code unterbringe damit dieser in einer Datei geloggt wird und zusätzlich im Terminal angezeigt wird.
Hier der wichtigste Teil meines Backup Codes:
backup_process = subprocess.Popen(rsync_liste, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = backup_process.communicate()
Habe schon verschiedenes Probiert, aber ich bekomm nie was im Terminal angezeigt und die Datei die mir mittels des Logging-Codes erstellt wird bleibt leer.
1 Antwort
Das geht mit logging:
https://docs.python.org/3/howto/logging.html
https://docs.python.org/3/library/logging.html
Du musst dir einen FileHandler und einen Streamhandler definieren, und die dann per addHandler hinzufügen.
import logging
logger = [logging.getLogger(name), logging.getLogger(name2)]
fh = logging.FileHandler(filename)
fh.setLevel(logging.DEBUG)
sh = logging.StreamHandler()
sh.setLevel(logging.DEBUG)
formatter = logging.Formatter('[%(asctime)s] %(levelname)-2s %(name)-4s \n%(message)s', "%d.%m.%y %H:%M:%S")
sh.setFormatter(formatter)
fh.setFormatter(formatter)
for log in logger:
log.addHandler(fh)
log.addHandler(sh)
log.setLevel(logging.DEBUG)
https://www.saltycrane.com/blog/2008/09/how-get-stdout-and-stderr-using-python-subprocess-module/
Je nach Anwendungsfall finde ich aber subprocess.check_output() einfacher.
import subprocess
import logging
log = logging.getLogger('mein_logger')
fh = logging.FileHandler("testlog")
fh.setLevel(logging.DEBUG)
sh = logging.StreamHandler()
sh.setLevel(logging.DEBUG)
formatter = logging.Formatter('[%(asctime)s] %(levelname)-2s %(name)-4s \n%(message)s', "%d.%m.%y %H:%M:%S")
sh.setFormatter(formatter)
fh.setFormatter(formatter)
log.addHandler(fh)
log.addHandler(sh)
log.setLevel(logging.DEBUG)
cmd = ["ls"]
test = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
output = test.stdout.read()
log.debug(output)
Hmm. Vielen Dank.
Kann ich bei filename ein Path-Objekt einfügen? Oder einfach Pfad/Dateiname als String?
Wird mit dem StreamHandler() dann die Ausgabe im Terminal gemacht?
Sorry dass ich nochmal nach frage.
Aber vielen Dank schonmal für die nette und ausführliche Hilfe.
Es tut mir leid, aber ich bräuchte nochmal Hilfe. Such jetzt schon eine Zeitlang im Internet, aber ich hab noch nicht so richtig gefunden wie ich dass auf den subprocess anwende:
Wie kann man diesen process loggen?
Wäre sehr dankbar wenn du mir nochmal helfen könntest.
Nachtrag:
Zur Info:
rsync_liste schaut z.b.: so aus: