Aussagekräftig

Die Weiterentwicklung von rbackup.py wird nicht langweilig, und nach einigen Monaten erscheinen mir meine PGP-signierten Backup-Benachrichtigungen zu wenig aussagekräftig. Den Output von rsync aufzugreifen, ist relativ einfach (stdout=subprocess.PIPE), aber um ihn parallel (wie bisher) im Terminal auszugeben, muss der aufgefangene Output manuell in das Terminal-Fenster gedruckt werden. Dazu wird der Parameter universal_newlines der subprocess.run-Methode verwendet, so dass ein String- statt eines Bytes-Objektes ausgegeben wird. Dieses String-Objekt wiederum lässt sich zeilenweise iterieren:

rsync_process = subprocess.run(command_list, stdout=subprocess.PIPE, universal_newlines=True) for stdout_line in rsync_process.stdout: print(stdout_line, end='')

Das ist nicht weiter kompliziert, aber es funktioniert nicht – der rsync-Output erscheint erst nach dem Abschluss des Subprozesses. Weil eine funktionierende Lösung unangemessen aufwendig ist, lasse ich der Nutzerin die Wahl zwischen einer aussagekräftigen Benachrichtigung und einer Ausgabe im Terminal (mit der Option -q):

rsync_output = '' if self.quiet: rsync_process = subprocess.run(command_list) else: print('Backing up, please be patient...') rsync_process = subprocess.run(command_list, stdout=subprocess.PIPE) rsync_output = rsync_process.stdout.decode()

Auch auf einen animierten Wartestandsanzeiger verzichte ich aus Kostengründen.

rsync_output wird in jedem Fall an logging() übergeben und dort ausgewertet. Als Belege für einen Datentransfer werden auf Stackoverflow die Zeichen > und < genannt (was den rsync-Parameter --itemize-changes für das entsprechende Logging erfordert), aber für meine Zwecke genügt ein einfacherer Test. Wenn zwischen dem initialen (sending|receiving) incremental file list und dem abschließenden sent lediglich zwei Zeilenumbrüche stehen, wird der Output nicht beigefügt:

if rsync_return_code == 0 or rsync_return_code == 24: unchanged = re.search('(sending|receiving) incremental file list\n\nsent', rsync_output) if unchanged: status = 'No files were transferred.' else: status = 'File transfer completed successfully (details below).' else: status = 'Failure, please re-run.' elapsed_time = end_time - start_time message = f'{self.summary}\nElapsed time: {elapsed_time}\nStatus: {status}' if not unchanged: message += f'\n\n==========\n{rsync_output}=========='

Bei umfangreicheren Backups erzeugt rbackup.py auf diese Weise längere Benachrichtigungen (> 50KB) und das angenehme Gefühl emsiger Geschäftigkeit.