Sobrescriba los archivos de solo lectura existentes al usar el archivo tar de Python

Estoy intentando usar el módulo tarfile de Python para extraer un archivo tar.gz.

Me gustaría la extracción para sobrescribir cualquier archivo de destino si ya existen, este es el comportamiento normal de tarfile.

Sin embargo, estoy golpeando a un snitch porque algunos de los archivos tienen protección contra escritura (por ejemplo, chmod 550).

La operación tarfile.extractall() falla realmente:

 IOError: [Errno 13] Permission denied '/foo/bar/file' 

Si bash eliminar los archivos de la línea de comandos normal, puedo hacerlo, solo necesito responder un mensaje:

 $ rm  rm: : override protection 550 (yes/no)? yes 

La utilidad tar de GNU normal también maneja estos archivos sin esfuerzo, simplemente los sobrescribe cuando los extraes.

Mi usuario es el propietario de los archivos, por lo que no sería difícil modificar recursivamente los archivos de destino antes de ejecutar tarfile.extractall. O puedo usar shutil.rmtree para volar el objective de antemano, que es la solución que estoy usando ahora … Sin embargo, eso se siente un poco pirateado.

¿Existe una forma más Pythonic de manejar la sobrescritura de archivos de solo lectura dentro de un archivo tar, usando excepciones o algo similar?

Podría pasar sobre los miembros del archivo tar y extraer / manejar errores en cada archivo:

En una versión moderna de Python usaría with statement:

 import os, tarfile with tarfile.TarFile('myfile.tar', 'r', errorlevel=1) as tar: for file_ in tar: try: tar.extract(file_) except IOError as e: os.remove(file_.name) tar.extract(file_) finally: os.chmod(file_.name, file_.mode) 

Si no puede usar with solo reemplazar el bloque de statement con:

 tarball = tarfile.open('myfile.tar', 'r', errorlevel=1) for file_ in tar: 

Si tu bola de alquitrán está comprimida, hay un atajo rápido para manejarlo con solo:

 tarfile.open('myfile.tar.gz', 'r:gz') 

Sería mejor si tarfile.extractall tuviera una opción de sobrescritura.

Pude hacer que el código de Mike’s Steder funcionara así:

 tarball = tarfile.open(filename, 'r:gz') for f in tarball: try: tarball.extract(f) except IOError as e: os.remove(f.name) tarball.extract(f) finally: os.chmod(f.name, f.mode)