Overwrite existing read-only files when using Python's tarfile

末鹿安然 提交于 2019-12-20 19:47:22

问题


I'm attempting to use Python's tarfile module to extract a tar.gz archive.

I'd like the extraction to overwrite any target files it they already exist - this is tarfile's normal behaviour.

However, I'm hitting a snitch in that some of the files have write-protection on (e.g. chmod 550).

The tarfile.extractall() operation actually fails:

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

If I try to delete the files from the normal command-line, I can do it, I just need to answer a prompt:

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

The normal GNU tar utility also handles these files effortlessly - it just overwrites them when you extract.

My user is the owner of the files, so it wouldn't be hard to recursively chmod the target files before running tarfile.extractall. Or I can use shutil.rmtree to blow away the target beforehand, which is the workaround I'm using now.. However, that feels a little hackish.

Is there a more Pythonic way of handle overwriting read-only files within tarfile, using exceptions, or something similar?


回答1:


You could loop over the members of the tarball and extract / handle errors on each file:

In a modern version of Python I'd use the 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)

If you can't use with just replace the with statement block with:

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

If your tar ball is gzipped there's a quick shortcut to handle that with just:

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

It would be nicer if tarfile.extractall had an overwrite option.




回答2:


I was able to get Mike's Steder's code to work like this:

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)


来源:https://stackoverflow.com/questions/7237475/overwrite-existing-read-only-files-when-using-pythons-tarfile

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!