12

Pythonのtarfileモジュールを使用してtar.gzアーカイブを抽出しようとしています。

抽出によって、すでに存在するターゲットファイルを上書きしたいのですが、これはtarfileの通常の動作です。

ただし、一部のファイルで書き込み保護がオンになっているという点で問題が発生しています(chmod 550など)。

操作はtarfile.extractall()実際には失敗します:

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

通常のコマンドラインからファイルを削除しようとすると、それを実行できます。プロンプトに応答するだけです。

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

通常のGNUtarユーティリティも、これらのファイルを簡単に処理します。抽出すると、ファイルが上書きされるだけです。

私のユーザーはファイルの所有者であるため、tarfile.extractallを実行する前にターゲットファイルを再帰的にchmodすることは難しくありません。または、shutil.rmtreeを使用して、事前にターゲットを吹き飛ばすことができます。これは、現在使用している回避策です。ただし、これは少しハックな感じがします。

tarfile内の読み取り専用ファイルの上書き、例外の使用などを処理する、よりPython的な方法はありますか?

4

2 に答える 2

10

tarballのメンバーをループして、各ファイルのエラーを抽出/処理できます。

Pythonの最新バージョンでは、次のwithステートメントを使用します。

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)

使用できない場合は、ステートメントブロックを次のようwithに置き換えてください。with

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

tarボールがgzipで圧縮されている場合は、次の方法でそれを処理するための簡単なショートカットがあります。

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

tarfile.extractall上書きオプションが あればもっといいでしょう。

于 2011-08-30T00:49:32.890 に答える
2

Mike の Steder のコードを次のように動作させることができました。

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)
于 2012-06-19T17:49:43.720 に答える