Mir ist heute klar geworden, daß bzip2- oder gzip-komprimierte Tarballs auf DVDs eine äußerst schlechte Verpackung für Backups sind, da die Komprimierung dafür sorgt, daß ein kleiner Bitfehler an irgendeiner Stelle den ganzen Rest des Archivs unlesbar machen kann.

Ein wenig Recherche ließ mich schnell damit liebäugeln, meine Tarballs in afio-Archive umzuwandeln. afio komprimiert jede Datei einzeln und erzeugt auf diese Weise wesentlich fehlertolerantere Archive als tar -j. Leider gibt es nur eine wirklich universelle Möglichkeit, Archive verschiedener Formate ineinander umzuwandeln: altes Archiv vollständig entpacken, neues Archiv zusammenpacken. Dieser Weg ist nun allerdings für viele meiner Backup-Tarballs inakzeptabel, weil ich genügend Platz auf der Festplatte selten habe. Effizient (d.h. ohne ständiges Durchsuchen des Ursprungstarballs von Anfang an) kriegt man es anders auch sehr wahrscheinlich nicht hin, außer man schreibt sich ein eigenes Programm dafür, das den Tarball selbst Stück für Stück verarbeitet.

Ein Glück, daß Python solcherlei Dinge von Haus aus kann. Der folgende Code macht aus einem Tarball (erstes Befehlszeilenargument) ein cpio-Archiv, in dem die Dateien jeweils mit lzma komprimiert wurden. afio kann solche Archive direkt entpacken (afio -iZP lzma).

#! /usr/bin/env python  
 
import os  
import subprocess  
import sys  
import tarfile  
 
tar = tarfile.open(sys.argv[1], "r|*")  
afio_name = sys.argv[2]  
 
cpio = subprocess.Popen(["cpio", "-o", "-c0", "--file=%s" % afio_name])  
 
for info in tar:  
    tar.extract(info)  
    file_name = info.name  
    if info.isfile():  
        os.spawnlp(os.P_WAIT, "lzma", "lzma", "-S", ".z", info.name)  
        file_name += ".z"  
    cpio = subprocess.Popen(["cpio", "-o", "-c0A", "--file=%s" % afio_name], stdin=subprocess.PIPE)  
    cpio.communicate(file_name + "\x00")  
    cpio.stdin.close()  
    cpio.wait()  
    if not info.isdir():  
        os.unlink(file_name)  
 
tar.close()