tarfile --- tar アーカイブファイルの読み書き

ソースコード: Lib/tarfile.py


tarfile モジュールを使うと、gzip、bz2、lzma で圧縮されたものを含め、tar アーカイブを読み書きできます。 .zip ファイルの読み書きには zipfile モジュールか、shutil の高水準の関数を使ってください。

いくつかの事実と形態:

  • モジュールが利用可能な場合、gzip、bz2、compression.zstd ならびに lzma で圧縮されたアーカイブを読み書きします。

    これらの オプションのモジュール がお使いの CPython に含まれていない場合は、配布元 (Python を提供した人や組織) のドキュメントを確認してください。 配布する側の方は オプションのモジュールの要件 を参照してください。

  • POSIX.1-1988 (ustar) フォーマットの読み書きをサポートしています。

  • longname および longlink 拡張を含む GNU tar フォーマットの読み書きをサポートしています。スパースファイルの復元を含む sparse 拡張は読み込みのみサポートしています。

  • POSIX.1-2001 (pax) フォーマットの読み書きをサポートしています。

  • ディレクトリ、通常ファイル、ハードリンク、シンボリックリンク、FIFO、キャラクターデバイス、ブロックデバイスを扱えます。 また、タイムスタンプ、アクセス権、所有者などのファイル情報を取得・復元できます。

バージョン 3.3 で変更: lzma 圧縮をサポートしました。

バージョン 3.12 で変更: アーカイブの展開には フィルター を使います。 これにより、予想外の動作を招く機能や危険な機能を制限したり、それらの機能が想定内でアーカイブを完全に信頼していると明示したりできます。

バージョン 3.14 で変更: デフォルトの展開フィルターが data になりました。 絶対パスや展開先の外部を指すリンクなど、危険な機能の一部を許可しません。 以前のフィルターの動作は fully_trusted と同等でした。

バージョン 3.14 で変更: compression.zstd による Zstandard 圧縮をサポートするようになりました。

tarfile.open(name=None, mode='r', fileobj=None, bufsize=10240, **kwargs)

パス名 name の TarFile オブジェクトを返します。TarFile オブジェクトと、利用できるキーワード引数に関する詳細な情報については、TarFile オブジェクト 節を参照してください。

mode は 'filemode[:compression]' の形式をとる文字列でなければなりません。デフォルトの値は 'r' です。以下に mode のとりうる組み合わせすべてを示します:

mode

action

'r' または 'r:*'

圧縮方法に関して透過的に、読み込み用にオープンします (推奨)。

'r:'

非圧縮のアーカイブだけを読み込み用に開きます。

'r:gz'

gzip 圧縮で読み込み用にオープンします。

'r:bz2'

bzip2 圧縮で読み込み用にオープンします。

'r:xz'

lzma 圧縮で読み込み用にオープンします。

'r:zst'

Zstandard 圧縮で読み込み用にオープンします。

'x' or 'x:'

圧縮せずに tarfile を排他的に作成します。tarfile が既存の場合 FileExistsError 例外を送出します。

'x:gz'

gzip 圧縮で tarfile を作成します。tarfile が既存の場合 FileExistsError 例外を送出します。

'x:bz2'

bzip2 圧縮で tarfile を作成します。tarfile が既存の場合 FileExistsError 例外を送出します。

'x:xz'

lzma 圧縮で tarfile を作成します。tarfile が既存の場合 FileExistsError 例外を送出します。

'x:zst'

Zstandard 圧縮で tarfile を作成します。tarfile が既存の場合 FileExistsError 例外を送出します。

'a' または 'a:'

非圧縮で追記用にオープンします。ファイルが存在しない場合は新たに作成されます。

'w' または 'w:'

非圧縮で書き込み用にオープンします。

'w:gz'

gzip 圧縮で書き込み用にオープンします。

'w:bz2'

bzip2 圧縮で書き込み用にオープンします。

'w:xz'

lzma 圧縮で書き込み用にオープンします。

'w:zst'

Zstandard 圧縮で書き込み用にオープンします。

'a:gz'、'a:bz2'、'a:xz' は利用できないことに注意して下さい。もし mode が、ある (圧縮した) ファイルを読み込み用にオープンするのに適していないなら、ReadError が送出されます。これを防ぐには mode 'r' を使って下さい。もし圧縮方式がサポートされていなければ、CompressionError が送出されます。

もし fileobj が指定されていれば、それは name でバイナリモードでオープンされた ファイルオブジェクト の代替として使うことができます。そのファイルオブジェクトの位置が 0 であることを前提に動作します。

'w:gz'、'x:gz'、'w|gz'、'w:bz2'、'x:bz2'、'w|bz2' モードでは、tarfile.open() はファイルの圧縮レベルを指定するキーワード引数 compresslevel (デフォルトは 6) を受け取ります。

'w:xz'、'x:xz' および 'w|xz' モードの場合、tarfile.open() はファイルの圧縮レベルを指定するキーワード引数 preset を受け付けます。

'w:zst'、'x:zst'、'w|zst' モードでは、tarfile.open() はファイルの圧縮レベルを指定するキーワード引数 level を受け取ります。 キーワード引数 options には、CompressionParameter で説明する Zstandard の詳細な圧縮パラメーターを指定できます。 キーワード引数 zstd_dict には、少量のデータの圧縮率を高めるために使う Zstandard の辞書 ZstdDict を指定できます。

'w:gz' と 'w|gz' モードでは、tarfile.open() はキーワード引数 mtime を受け取り、その mtime を持つ gzip アーカイブヘッダーを作成します。 デフォルトでは mtime はアーカイブの作成時刻です。 再現可能な出力を得るために、作成時刻に依存しない圧縮ストリームを生成するには、mtime に 0 を指定してください。

特別な用途のため、mode にはもう 1 つの形式 'filemode|[compression]' があります。 tarfile.open() は、データをブロックのストリームとして処理する TarFile オブジェクトを返します。 ファイル内のランダムなシークは行いません。 fileobj を指定する場合は、バイト列を扱う read() または write() メソッド (mode による) を持つオブジェクトなら何でも使えます。 bufsize はブロックサイズを指定し、デフォルトは 20 * 512 バイトです。 この形式は、例えば sys.stdin.buffer、ソケットの ファイルオブジェクト、テープデバイスと組み合わせて使います。 ただし、このような TarFile オブジェクトはランダムアクセスができないという制約があります。 使用例 を参照してください。 現在使えるモードは次のとおりです:

モード

動作

'r|*'

tar ブロックの stream を圧縮方法に関して透過的に読み込み用にオープンします。

'r|'

非圧縮 tar ブロックの stream を読み込み用にオープンします。

'r|gz'

gzip 圧縮の stream を読み込み用にオープンします。

'r|bz2'

bzip2 圧縮の stream を読み込み用にオープンします。

'r|xz'

lzma 圧縮の stream を読み込み用にオープンします。

'r|zst'

Zstandard 圧縮の stream を読み込み用にオープンします。

'w|'

非圧縮の stream を書き込み用にオープンします。

'w|gz'

gzip 圧縮の stream を書き込み用にオープンします。

'w|bz2'

bzip2 圧縮の stream を書き込み用にオープンします。

'w|xz'

lzma 圧縮の stream を書き込み用にオープンします。

'w|zst'

Zstandard 圧縮の stream を書き込み用にオープンします。

バージョン 3.5 で変更: 'x' (排他的作成) モードが追加されました。

バージョン 3.6 で変更: name パラメタが path-like object を受け付けるようになりました。

バージョン 3.12 で変更: compresslevel キーワード引数がストリームにも使えるようになりました。

バージョン 3.14 で変更: preset キーワード引数がストリームにも使えるようになりました。

バージョン 3.15 で変更: デフォルトの圧縮レベルが 9 から 6 に下がりました。 これはほとんどの圧縮ツールのデフォルトで、速度と性能のバランスがよりよいレベルです。

class tarfile.TarFile

tar アーカイブを読み書きするためのクラスです。このクラスを直接使わないこと: 代わりに tarfile.open() を使ってください。TarFile オブジェクト を参照してください。

tarfile.is_tarfile(name)

name が tarfile モジュールで読み取れる tar アーカイブファイルなら、True を返します。 name には str、ファイル、ファイル類似オブジェクトを指定できます。

バージョン 3.9 で変更: ファイルおよびファイルライクオブジェクトをサポートしました。

tarfile モジュールは以下の例外を定義しています:

exception tarfile.TarError

tarfile のすべての例外の基底クラスです。

exception tarfile.ReadError

tarfile モジュールで扱えないか、何らかの点で不正な tar アーカイブを開いたときに送出されます。

exception tarfile.CompressionError

圧縮方法がサポートされていないか、あるいはデータを正しくデコードできない時に送出されます。

exception tarfile.StreamError

ストリームのような TarFile オブジェクトで典型的な制限のために送出されます。

exception tarfile.ExtractError

TarFile.extract() を使った時に 致命的でない エラーに対して送出されます。ただし TarFile.errorlevel== 2 の場合に限ります。

exception tarfile.HeaderError

TarInfo.frombuf() メソッドが取得したバッファーが不正だったときに送出されます。

exception tarfile.FilterError

フィルターがメンバーを 拒否 したときの例外の基底クラスです。

tarinfo

フィルターが展開を拒否したメンバーの情報を表す TarInfo です。

exception tarfile.AbsolutePathError

絶対パスを持つメンバーの展開を拒否するために送出されます。

exception tarfile.OutsideDestinationError

展開先ディレクトリの外部へのメンバーの展開を拒否するために送出されます。

exception tarfile.SpecialFileError

特殊ファイル (デバイスやパイプなど) の展開を拒否するために送出されます。

exception tarfile.AbsoluteLinkError

絶対パスを指すシンボリックリンクの展開を拒否するために送出されます。

exception tarfile.LinkOutsideDestinationError

展開先ディレクトリの外部を指すシンボリックリンクの展開を拒否するために送出されます。

exception tarfile.LinkFallbackError

別のアーカイブメンバーを展開してリンク (ハードリンクまたはシンボリックリンク) を模倣しようとした際に、そのメンバーがフィルターで拒否される場合、模倣を拒否するために送出されます。 代わりに展開するメンバーを拒否した例外は BaseException.__context__ から取得できます。

Added in version 3.15.

モジュールレベルで以下の定数が利用できます。

tarfile.ENCODING

既定の文字エンコーディング。Windows では 'utf-8' 、それ以外では sys.getfilesystemencoding() の返り値です。

tarfile.REGTYPE
tarfile.AREGTYPE

通常ファイルを表す type。

tarfile.LNKTYPE

アーカイブ内のリンクを表す type。

tarfile.SYMTYPE

シンボリックリンクを表す type。

tarfile.CHRTYPE

キャラクター特殊デバイスを表す type。

tarfile.BLKTYPE

ブロック特殊デバイスを表す type。

tarfile.DIRTYPE

ディレクトリを表す type。

tarfile.FIFOTYPE

FIFO 特殊デバイスを表す type。

tarfile.CONTTYPE

連続ファイルを表す type。

tarfile.GNUTYPE_LONGNAME

GNU tar の longname を表す type。

GNU tar の longlink を表す type。

tarfile.GNUTYPE_SPARSE

GNU tar のスパースファイルを表す type。

次の定数はそれぞれ、tarfile モジュールで作成できる tar アーカイブの形式を表します。 詳しくは サポートしている tar フォーマット 節を参照してください。

tarfile.USTAR_FORMAT

POSIX.1-1988 (ustar) フォーマット。

tarfile.GNU_FORMAT

GNU tar フォーマット。

tarfile.PAX_FORMAT

POSIX.1-2001 (pax) フォーマット。

tarfile.DEFAULT_FORMAT

アーカイブを作成する際のデフォルトのフォーマット。現在は PAX_FORMAT です。

バージョン 3.8 で変更: 新しいアーカイブのデフォルトフォーマットが GNU_FORMAT から PAX_FORMAT に変更されました。

参考

zipfile モジュール

zipfile 標準モジュールのドキュメント。

アーカイブ化操作

shutil が提供するより高水準のアーカイブ機能についてのドキュメント。

GNU tar manual, Basic Tar Format

GNU tar 拡張機能を含む、tar アーカイブファイルのためのドキュメント。

TarFile オブジェクト

TarFile オブジェクトは、tar アーカイブへのインターフェースを提供します。tar アーカイブは一連のブロックです。アーカイブメンバー (保存されたファイル) は、ヘッダーブロックとそれに続くデータブロックで構成されています。一つの tar アーカイブにファイルを何回も保存することができます。各アーカイブメンバーは、TarInfo オブジェクトで確認できます。詳細については TarInfo オブジェクト を参照してください。

TarFile オブジェクトは with 文のコンテキストマネージャーとして利用できます。with ブロックが終了したときにオブジェクトはクローズされます。例外が発生した時、内部で利用されているファイルオブジェクトのみがクローズされ、書き込み用にオープンされたアーカイブのファイナライズは行われないことに注意してください。使用例 節のユースケースを参照してください。

Added in version 3.2: コンテキスト管理のプロトコルがサポートされました。

class tarfile.TarFile(name=None, mode='r', fileobj=None, format=DEFAULT_FORMAT, tarinfo=TarInfo, dereference=False, ignore_zeros=False, encoding=ENCODING, errors='surrogateescape', pax_headers=None, debug=0, errorlevel=1, stream=False)

以下のすべての引数はオプションで、インスタンス属性としてもアクセスできます。

name はアーカイブのパス名で、パス類似オブジェクト も指定できます。 fileobj を指定した場合は省略できます。 その場合、ファイルオブジェクトに name 属性があればそれを使います。

mode は、既存のアーカイブから読み込むための 'r'、既存のアーカイブに追記するための 'a'、既存のファイルがあれば上書きして新しいファイルを作成する 'w' 、あるいは存在しない場合にのみ新しいファイルを作成する 'x' のいずれかです。

fileobj が与えられていれば、それを使ってデータを読み書きします。もしそれが決定できれば、mode は fileobj のモードで上書きされます。fileobj は位置 0 から利用されます。

注釈

TarFile をクローズした時、fileobj はクローズされません。

format はアーカイブの書き込みフォーマットを制御します。モジュールレベルで定義されている、USTAR_FORMAT、GNU_FORMAT、あるいは PAX_FORMAT のいずれかである必要があります。 読み出しのときは、1 つのアーカイブに異なるフォーマットが混在していたとしても、フォーマットは自動的に検知されます。

tarinfo 引数を利用して、デフォルトの TarInfo クラスを別のクラスで置き換えることができます。

dereference が False だった場合、シンボリックリンクやハードリンクがアーカイブに追加されます。True だった場合、リンクのターゲットとなるファイルの内容がアーカイブに追加されます。シンボリックリンクをサポートしていないシステムでは効果がありません。

ignore_zeros が False の場合、空のブロックをアーカイブの終端として扱います。 True の場合は、空のブロックと不正なブロックをスキップし、できる限り多くのメンバーを取得しようとします。 これは、連結されたアーカイブや破損したアーカイブの読み取りにのみ役立ちます。

debug は 0 (デバッグメッセージ無し) から 3 (全デバッグメッセージ) まで設定できます。このメッセージは sys.stderr に書き込まれます。

errorlevel は展開時のエラーの処理方法を制御します。 対応する属性 を参照してください。

encoding 引数はアーカイブの読み書きに使う文字エンコーディングを、errors 引数は文字変換エラーの処理方法を指定します。 ほとんどのユーザーはデフォルト設定のまま利用できます。 詳細は Unicode に関する問題 節を参照してください。

引数 pax_headers は、オプションの文字列辞書で、format が PAX_FORMAT だった場合に pax グローバルヘッダーに追加されます。

stream を True にすると、アーカイブの読み取り中に内部のファイルの情報をキャッシュせず、メモリを節約します。

バージョン 3.2 で変更: 引数 errors のデフォルトが 'surrogateescape' になりました。

バージョン 3.5 で変更: 'x' (排他的作成) モードが追加されました。

バージョン 3.6 で変更: name パラメタが path-like object を受け付けるようになりました。

バージョン 3.13 で変更: stream 引数が追加されました。

classmethod TarFile.open(...)

代替コンストラクターです。モジュールレベルでの tarfile.open() 関数は、実際はこのクラスメソッドへのショートカットです。

TarFile.getmember(name)

メンバー name に対する TarInfo オブジェクトを返します。name がアーカイブに見つからなければ、KeyError が送出されます。

注釈

アーカイブ内に同じメンバーが複数回現れる場合は、最後に現れるものを最新のバージョンとみなします。

TarFile.getmembers()

アーカイブのメンバーを TarInfo オブジェクトのリストとして返します。 リストの順序は、アーカイブ内のメンバーの順序と同じです。

TarFile.getnames()

メンバーをその名前のリストを返します。これは getmembers() で返されるリストと同じ順番です。

TarFile.list(verbose=True, *, members=None)

内容の一覧を sys.stdout に出力します。verbose が False の場合、メンバー名のみ表示します。True の場合、 ls -l に似た出力を生成します。オプションの members を与える場合、 getmembers() が返すリストのサブセットである必要があります。

バージョン 3.5 で変更: members 引数が追加されました。.

TarFile.next()

TarFile が読み込み用にオープンされている時、アーカイブの次のメンバーを TarInfo オブジェクトとして返します。もしそれ以上利用可能なものがなければ、None を返します。

TarFile.extractall(path='.', members=None, *, numeric_owner=False, filter=None)

すべてのメンバーをアーカイブから現在の作業ディレクトリまたは path に抽出します。オプションの members が与えられるときには、getmembers() で返されるリストの一部でなければなりません。所有者、変更時刻、アクセス権限のようなディレクトリ情報はすべてのメンバーが抽出された後にセットされます。これは二つの問題を回避するためです。一つはディレクトリの変更時刻はその中にファイルが作成されるたびにリセットされるということ、もう一つはディレクトリに書き込み許可がなければその中のファイル抽出は失敗してしまうということです。

numeric_owner が True の場合、tarfile の uid と gid 数値が抽出されたファイルのオーナー/グループを設定するために使用されます。False の場合、tarfile の名前付きの値が使用されます。

filter 引数は、展開前に members をどのように変更または拒否するかを指定します。 詳しくは 展開フィルター を参照してください。 この引数を明示的に設定するのは、特定の tar の機能が必要な場合、またはデフォルトの安全性が低い Python (3.13 以前) に対応するため filter='data' とする場合だけにすることを推奨します。

警告

信頼できない提供元のアーカイブは、事前に調べずに展開してはいけません。

Python 3.14 以降、デフォルトの data は最も危険なセキュリティ上の問題を防ぎます。 ただし、意図しない動作や安全でない動作の すべて を防ぐものではありません。 詳しくは 展開フィルター 節を参照してください。

バージョン 3.5 で変更: numeric_owner 引数が追加されました。

バージョン 3.6 で変更: path パラメタが path-like object を受け付けるようになりました。

バージョン 3.12 で変更: filter パラメータが追加されました。

バージョン 3.14 で変更: filter 引数のデフォルトが 'data' になりました。

TarFile.extract(member, path='', set_attrs=True, *, numeric_owner=False, filter=None)

アーカイブからメンバーの完全な名前を使って、現在のディレクトリに展開します。ファイル情報はできる限り正確に展開されます。 member はファイル名もしくは TarInfo オブジェクトです。 path を使って別のディレクトリを指定することもできます。 path は path-like object でも構いません。set_attrs が false でない限り、ファイルの属性 (所有者、最終更新時刻、モード) は設定されます。

numeric_owner 引数と filter 引数は extractall() と同じです。

注釈

extract() メソッドはいくつかの展開に関する問題を扱いません。ほとんどの場合、extractall() メソッドの利用を考慮するべきです。

警告

信頼できない提供元のアーカイブは、事前に調べずに展開してはいけません。 詳しくは extractall() の警告を参照してください。

バージョン 3.2 で変更: パラメーターに set_attrs を追加しました。

バージョン 3.5 で変更: numeric_owner 引数が追加されました。

バージョン 3.6 で変更: path パラメタが path-like object を受け付けるようになりました。

バージョン 3.12 で変更: filter パラメータが追加されました。

TarFile.extractfile(member)

アーカイブからメンバーをファイルオブジェクトとして抽出します。 member はファイル名でも TarInfo オブジェクトでも構いません。member が一般ファイルまたはリンクの場合、io.BufferedReader オブジェクトが返されます。 存在するそれ以外のメンバーでは、 None が返されます。 アーカイブに member が存在しない場合は KeyError が送出されます。

バージョン 3.3 で変更: 戻り値が io.BufferedReader オブジェクトになりました。

バージョン 3.13 で変更: 返される io.BufferedReader オブジェクトに、常に 'rb' となる mode 属性が追加されました。

TarFile.errorlevel: int

errorlevel が 0 の場合、TarFile.extract() と TarFile.extractall() の使用時のエラーを無視します。 ただし、debug が 0 より大きければ、デバッグ出力にエラーメッセージを表示します。 1 (デフォルト) の場合は、すべての 致命的な エラーを OSError または FilterError 例外として送出します。 2 の場合は、致命的でない エラーもすべて TarError 例外として送出します。

引数の型の誤りやデータの破損によるものなど、常に送出される例外もあります。

独自の 展開フィルター は、致命的な エラーでは FilterError を、致命的でない エラーでは ExtractError を送出する必要があります。

例外が送出された時点で、アーカイブの一部が展開済みになっている場合があります。 クリーンアップは利用者が行う必要があります。

TarFile.extraction_filter

Added in version 3.12.

extract() と extractall() の filter 引数のデフォルトとして使う 展開フィルター です。

この属性には None または呼び出し可能オブジェクトを指定できます。 extract() の filter 引数と異なり、文字列の名前は指定できません。

extraction_filter が None (デフォルト) の場合、展開メソッドはデフォルトで data フィルターを使います。

この属性はインスタンスに設定でき、サブクラスでオーバーライドすることもできます。 TarFile クラス自体に設定して全体のデフォルトにすることも可能ですが、tarfile を使うすべての処理に影響するため、トップレベルのアプリケーションや サイトの設定 でのみ行うのが適切です。 このように全体のデフォルトを設定する場合は、self 引数が渡されないように、フィルター関数を @staticmethod でラップする必要があります。

バージョン 3.14 で変更: デフォルトのフィルターが data になりました。 絶対パスや展開先の外部を指すリンクなど、危険な機能の一部を許可しません。 以前のデフォルトは fully_trusted と同等でした。

TarFile.add(name, arcname=None, recursive=True, *, filter=None)

ファイル name をアーカイブに追加します。 name は、任意のファイルタイプ (ディレクトリ、fifo、シンボリックリンク等)です。 arcname が与えられている場合は、それはアーカイブ内のファイルの代替名を指定します。 デフォルトではディレクトリは再帰的に追加されます。 これは、 recursive を False に設定すると避けられます。 再帰処理はソートされた順序でエントリーを追加します。 filter が与えられた場合、それは TarInfo オブジェクトを引数として受け取り、操作した TarInfo オブジェクトを返す関数でなければなりません。 代わりに None を返した場合、 TarInfo オブジェクトはアーカイブから除外されます。 使用例 にある例を参照してください。

バージョン 3.2 で変更: filter パラメータが追加されました。

バージョン 3.7 で変更: 再帰処理はソートされた順序でエントリーを追加するようになりました。

TarFile.addfile(tarinfo, fileobj=None)

TarInfo オブジェクト tarinfo をアーカイブに追加します。 tarinfo がサイズのゼロでない通常ファイルを表す場合は、fileobj 引数に バイナリファイル を指定する必要があり、そこから tarinfo.size バイトを読み取ってアーカイブに追加します。 TarInfo オブジェクトは直接作成することも、gettarinfo() を使って作成することもできます。

バージョン 3.13 で変更: サイズのゼロでない通常ファイルには fileobj の指定が必須になりました。

TarFile.gettarinfo(name=None, arcname=None, fileobj=None)

既存のファイルに対する os.stat() または同等の処理の結果から TarInfo オブジェクトを作成します。 ファイルは name で指定するか、ファイル記述子を持つ file object を fileobj に渡して指定します。 name には path-like object も指定できます。 arcname を指定すると、アーカイブ内ではその名前を使用します。 指定しない場合は、fileobj の name 属性または name 引数から名前を取得します。 名前はテキスト文字列にしてください。

addfile() で追加する前に、TarInfo の属性の一部を変更できます。 ファイルオブジェクトが、ファイルの先頭に位置する通常のファイルオブジェクトでない場合は、size などの属性を変更する必要があるかもしれません。 GzipFile のようなオブジェクトがこれに当たります。 name も変更できます。 その場合、arcname はダミーの文字列で構いません。

バージョン 3.6 で変更: name パラメタが path-like object を受け付けるようになりました。

TarFile.close()

TarFile をクローズします。書き込みモードでは、完了ゼロブロックが 2 個アーカイブに追加されます。

TarFile.pax_headers: dict

pax グローバルヘッダーに含まれる key-value ペアの辞書です。

TarInfo オブジェクト

TarInfo オブジェクトは TarFile の一つのメンバーを表します。ファイルに必要なすべての属性 (ファイルタイプ、ファイルサイズ、時刻、アクセス権限、所有者等のような) を保存する他に、そのタイプを決定するのに役に立ついくつかのメソッドを提供します。これにはファイルのデータそのものは 含まれません 。

TarInfo オブジェクトは、TarFile の getmember()、getmembers()、gettarinfo() メソッドが返します。

getmember() や getmembers() が返すオブジェクトを変更すると、その後のアーカイブに対するすべての操作に影響します。 これを避けたい場合は copy.copy() を使うか、replace() メソッドを呼び出して、変更を加えたコピーを一度に作成できます。

Several attributes can be set to None to indicate that a piece of metadata is unused or unknown. Different TarInfo methods handle None differently:

  • extract() と extractall() は、対応するメタデータを無視し、デフォルト値のままにします。

  • addfile() は失敗します。

  • list() は代わりの文字列を表示します。

class tarfile.TarInfo(name='')

TarInfo オブジェクトを作成します。

classmethod TarInfo.frombuf(buf, encoding, errors)

バイト列バッファー buf から TarInfo オブジェクトを作成して返します。

バッファーが不正な場合 HeaderError を送出します。

classmethod TarInfo.fromtarfile(tarfile)

TarFile オブジェクトの tarfile から、次のメンバーを読み込んで、それを TarInfo オブジェクトとして返します。

TarInfo.tobuf(format=DEFAULT_FORMAT, encoding=ENCODING, errors='surrogateescape')

TarInfo オブジェクトからバイト列バッファーを作成します。 引数については TarFile クラスのコンストラクターを参照してください。

バージョン 3.2 で変更: 引数 errors のデフォルトが 'surrogateescape' になりました。

TarInfo オブジェクトには以下のデータ属性があります:

TarInfo.name: str

アーカイブメンバーの名前。

TarInfo.size: int

バイト単位でのサイズ。

TarInfo.mtime: int | float

os.stat_result.st_mtime と同じ、エポック からの秒数で表した最終変更時刻です。

バージョン 3.12 で変更: extract() と extractall() では None に設定でき、その場合は展開時にこの属性を適用しません。

TarInfo.mode: int

os.chmod() と同じアクセス権のビットです。

バージョン 3.12 で変更: extract() と extractall() では None に設定でき、その場合は展開時にこの属性を適用しません。

TarInfo.type

ファイルタイプ。type は通常、定数 REGTYPE、AREGTYPE、LNKTYPE、SYMTYPE、DIRTYPE、FIFOTYPE、CONTTYPE、CHRTYPE、BLKTYPE、あるいは GNUTYPE_SPARSE のいずれかです。TarInfo オブジェクトのタイプをもっと簡単に解決するには、下記の is*() メソッドを使って下さい。

TarInfo.linkname: str

リンク先ファイルの名前。これはタイプ LNKTYPE と SYMTYPE の TarInfo オブジェクトにだけ存在します。

シンボリックリンク (SYMTYPE) の linkname は、そのリンクを含むディレクトリからの相対パスです。 ハードリンク (LNKTYPE) の linkname は、アーカイブのルートからの相対パスです。

TarInfo.uid: int

ファイルメンバーを保存した元のユーザーのユーザー ID。

バージョン 3.12 で変更: extract() と extractall() では None に設定でき、その場合は展開時にこの属性を適用しません。

TarInfo.gid: int

ファイルメンバーを保存した元のユーザーのグループ ID。

バージョン 3.12 で変更: extract() と extractall() では None に設定でき、その場合は展開時にこの属性を適用しません。

TarInfo.uname: str

ファイルメンバーを保存した元のユーザーのユーザー名。

バージョン 3.12 で変更: extract() と extractall() では None に設定でき、その場合は展開時にこの属性を適用しません。

TarInfo.gname: str

ファイルメンバーを保存した元のユーザーのグループ名。

バージョン 3.12 で変更: extract() と extractall() では None に設定でき、その場合は展開時にこの属性を適用しません。

TarInfo.chksum: int

ヘッダーのチェックサム。

TarInfo.devmajor: int

デバイスのメジャー番号。

TarInfo.devminor: int

デバイスのマイナー番号。

TarInfo.offset: int

tar ヘッダーの開始位置。

TarInfo.offset_data: int

ファイルデータの開始位置。

TarInfo.sparse

スパースなメンバーの情報。

TarInfo.pax_headers: dict

pax 拡張ヘッダーに関連付けられた、key-value ペアの辞書。

TarInfo.replace(name=..., mtime=..., mode=..., linkname=..., uid=..., gid=..., uname=..., gname=..., deep=True)

Added in version 3.12.

指定された属性を変更した、TarInfo オブジェクトの 新しい コピーを返します。 例えば、グループ名を 'staff' にした TarInfo を返すには、次のようにします。

new_tarinfo = old_tarinfo.replace(gname='staff')

デフォルトでは深いコピーを作成します。 deep が偽の場合は浅いコピーとなり、pax_headers や独自の属性は元の TarInfo オブジェクトと共有されます。

TarInfo オブジェクトは便利な照会用のメソッドもいくつか提供しています:

TarInfo.isfile()

TarInfo オブジェクトが通常ファイルを表す場合、True を返します。

TarInfo.isreg()

isfile() と同じです。

TarInfo.isdir()

ディレクトリの場合に True を返します。

TarInfo.issym()

シンボリックリンクの場合に True を返します。

TarInfo.islnk()

ハードリンクの場合に True を返します。

TarInfo.ischr()

キャラクターデバイスの場合に True を返します。

TarInfo.isblk()

ブロックデバイスの場合に True を返します。

TarInfo.isfifo()

FIFO の場合に True を返します。

TarInfo.isdev()

キャラクターデバイス、ブロックデバイスあるいは FIFO のいずれかの場合に True を返します。

展開フィルター

Added in version 3.12.

tar 形式は、UNIX 系ファイルシステムのあらゆる詳細を記録できるよう設計されており、非常に強力です。 しかし、その機能により、展開時に意図しない動作や、悪意のある動作を引き起こす tar ファイルを簡単に作れてしまいます。 例えば、絶対パス、パスの .. 要素、後続のメンバーに影響するシンボリックリンクなど、さまざまな方法で任意のファイルを上書きできます。

ほとんどの場合、すべての機能は必要ありません。 そこで tarfile は、機能を制限してセキュリティ上の問題の一部を軽減する仕組みとして、展開フィルターをサポートしています。

警告

利用可能なフィルターのどれも、危険なアーカイブの機能を すべて 防げるわけではありません。 信頼できない提供元のアーカイブは、事前に調べずに展開してはいけません。 追加の検証のヒント も参照してください。

参考

PEP 706

設計の動機と根拠をさらに詳しく説明しています。

TarFile.extract() と extractall() の filter 引数には、次のものを指定できます:

  • 文字列 'fully_trusted': アーカイブに指定されたすべてのメタデータをそのまま適用します。 利用者がアーカイブを完全に信頼している場合や、独自の複雑な検証を実装している場合に使ってください。

  • 文字列 'tar': tar 固有の機能 (UNIX 系ファイルシステムの機能) の大部分をそのまま適用しますが、予想外の動作や悪意のある動作につながる可能性が非常に高い機能は拒否します。 詳しくは tar_filter() を参照してください。

  • 文字列 'data': UNIX 系ファイルシステムに固有の機能の大部分を無視または拒否します。 クロスプラットフォームのデータアーカイブの展開を想定しています。 詳しくは data_filter() を参照してください。

  • None (デフォルト): TarFile.extraction_filter を使います。

    それも None (デフォルト) の場合は、'data' フィルターを使います。

    バージョン 3.14 で変更: デフォルトのフィルターが data になりました。 以前のデフォルトは fully_trusted と同等でした。

  • 展開するメンバーごとに呼び出される、呼び出し可能オブジェクト。 メンバーを表す TarInfo と、アーカイブを展開する先のパスを受け取ります (すべてのメンバーに同じパスが渡されます)。

    filter(member: TarInfo, path: str, /) -> TarInfo | None
    

    この呼び出し可能オブジェクトは、各メンバーを展開する直前に呼ばれるため、その時点のディスクの状態を考慮できます。 次のいずれかの動作を行えます:

    • アーカイブ内のメタデータの代わりに使う TarInfo オブジェクトを返す。

    • None を返して、そのメンバーをスキップする。

    • 例外を送出する。 errorlevel に応じて、処理が中止されるか、そのメンバーがスキップされます。 展開を中止した場合、extractall() はアーカイブの一部を展開したまま残すことがあります。 クリーンアップは行いません。

組み込みの名前付きフィルター

あらかじめ定義された名前付きフィルターは関数として利用できるため、独自のフィルターで再利用できます:

tarfile.fully_trusted_filter(member, path)

member を変更せずに返します。

'fully_trusted' フィルターを実装します。

tarfile.tar_filter(member, path)

'tar' フィルターを実装します。

  • ファイル名の先頭のスラッシュ (/ と os.sep) を取り除きます。

  • 絶対パスを持つファイルの展開を 拒否 します (Windows の C:/foo など、スラッシュを取り除いても絶対パスである場合)。 AbsolutePathError を送出します。

  • .. 要素を含むファイル名 (TarInfo.name) を os.path.normpath() で正規化します。 これにより内部の .. 要素が取り除かれるため、シンボリックリンクを通る場合は名前の意味が変わることがあります。

  • シンボリックリンクをたどった後の絶対パスが展開先の外部になるファイルは、展開を 拒否 します。 OutsideDestinationError を送出します。

  • リンクの名前が展開先ディレクトリそのものを指すリンク (ハードリンクまたはシンボリックリンク) は、展開を 拒否 します。 OutsideDestinationError を送出します。 シンボリックリンクをサポートしないプラットフォームでも、これらのファイルは拒否されます。

  • モードの上位ビット (setuid、setgid、sticky) と、グループおよびその他のユーザーの書き込みビット (S_IWGRP | S_IWOTH) をクリアします。

変更後の TarInfo メンバーを返します。

バージョン 3.15 で変更: .. 要素を含むファイル名を正規化するようになりました。

tarfile.data_filter(member, path)

'data' フィルターを実装します。 tar_filter の処理に加え、次の処理を行います:

  • リンク先 (TarInfo.linkname) を os.path.normpath() で正規化します。 これにより内部の .. 要素が取り除かれるため、TarInfo.linkname のパスがシンボリックリンクを通る場合、リンクの意味が変わることがあります。

  • 絶対パスや展開先の外部を指すリンク (ハードリンクまたはシンボリックリンク) は、展開を 拒否 します。

    AbsoluteLinkError または LinkOutsideDestinationError を送出します。

    シンボリックリンクをサポートしないプラットフォームでも、これらのファイルは拒否されます。

  • デバイスファイル (パイプを含む) の展開を 拒否 します。 SpecialFileError を送出します。

  • ハードリンクを含む通常ファイルについては:

    • 所有者の読み取り・書き込み権限 (S_IRUSR | S_IWUSR) を設定します。

    • 所有者に実行権限 (S_IXUSR) がなければ、グループとその他のユーザーの実行権限 (S_IXGRP | S_IXOTH) を取り除きます。

  • ほかのファイル (ディレクトリ) については、mode を None に設定し、展開メソッドがアクセス権のビットを適用しないようにします。

  • ユーザーとグループの情報 (uid、gid、uname、gname) を None に設定し、展開メソッドがそれらを設定しないようにします。

変更後の TarInfo メンバーを返します。

このフィルターは、危険なアーカイブの機能を すべて 防ぐものではありません。 詳しくは 追加の検証のヒント を参照してください。

バージョン 3.15 で変更: リンク先を正規化するようになりました。

フィルターのエラー

フィルターがファイルの展開を拒否すると、FilterError のサブクラスである適切な例外を送出します。 TarFile.errorlevel が 1 以上なら、これによって展開を中止します。 errorlevel=0 の場合は、エラーを記録してそのメンバーをスキップし、展開を続けます。

追加の検証のヒント

filter='data' を使っても、tarfile は信頼できないファイルを事前の検査なしに展開する用途には適していません。 特に、あらかじめ定義されたフィルターはサービス拒否攻撃を防ぎません。 利用者が追加の検査を行う必要があります。

検討すべき事項の一部を挙げます:

  • 新しい一時ディレクトリ に展開してください。 既存のリンクの悪用などを防げるほか、展開に失敗した後のクリーンアップも容易になります。

  • シンボリックリンクが必要なければ、許可しないでください。

  • 信頼できないデータを扱う場合は、ディスク、メモリ、CPU の使用量を外部 (OS レベルなど) で制限してください。

  • 許可する文字のリストでファイル名を検査してください (制御文字、見分けにくい文字、ほかの環境のパス区切り文字などを除外するため)。

  • ファイル名の拡張子が想定どおりか確認してください (「クリックすると」実行されるファイルや、Windows の特殊デバイス名のように拡張子のないファイルを避けるため)。

  • 展開するファイル数、展開するデータの合計サイズ、ファイル名の長さ (シンボリックリンクの長さを含む)、個々のファイルのサイズを制限してください。

  • 大文字・小文字を区別しないファイルシステムで、ほかのファイルと名前が衝突して隠れてしまうファイルがないか確認してください。

次の点にも注意してください:

  • tar ファイルには、同じファイルの複数のバージョンを含められます。 後のバージョンが前のバージョンを上書きすることを想定しています。 この機能はテープアーカイブの更新に不可欠ですが、悪用される可能性があります。

  • tarfile は、処理中に変化するデータに起因する問題からは保護しません。 例えば、展開やアーカイブ作成の途中で、攻撃者が展開先 (または元) のディレクトリを操作する場合です。

古い Python バージョンへの対応

展開フィルターは Python 3.12 で追加されましたが、セキュリティ更新として古いバージョンにバックポートされる場合があります。 機能が利用できるか確認するには、Python のバージョンを調べるのではなく、例えば hasattr(tarfile, 'data_filter') を使ってください。

以下に、この機能がある Python とない Python の両方に対応する例を示します。 extraction_filter の設定は、その後のすべての操作に影響することに注意してください。

  • 完全に信頼するアーカイブの場合。

    my_tarfile.extraction_filter = (lambda member, path: member)
    my_tarfile.extractall()
    
  • 'data' フィルターがあれば使い、この機能がなければ Python 3.11 の動作 ('fully_trusted') に戻す場合。

    my_tarfile.extraction_filter = getattr(tarfile, 'data_filter',
                                           (lambda member, path: member))
    my_tarfile.extractall()
    
  • 'data' フィルターを使い、利用できなければ 失敗させる 場合。

    my_tarfile.extractall(filter=tarfile.data_filter)
    

    もしくは:

    my_tarfile.extraction_filter = tarfile.data_filter
    my_tarfile.extractall()
    
  • 'data' フィルターを使い、利用できなければ 警告する 場合。

    if hasattr(tarfile, 'data_filter'):
        my_tarfile.extractall(filter='data')
    else:
        # 必要がなくなったら、この処理を削除する
        warn_the_user('Extracting may be unsafe; consider updating Python')
        my_tarfile.extractall()
    

状態を持つ展開フィルターの例

tarfile の展開メソッドは単純な filter 呼び出し可能オブジェクトを受け取りますが、独自のフィルターは内部状態を持つ、より複雑なオブジェクトにもできます。 コンテキストマネージャーとして実装し、次のように使うと便利な場合があります。

with StatefulFilter() as filter_func:
    tar.extractall(path, filter=filter_func)

このようなフィルターは、例えば次のように書けます。

class StatefulFilter:
    def __init__(self):
        self.file_count = 0

    def __enter__(self):
        return self

    def __call__(self, member, path):
        self.file_count += 1
        return member

    def __exit__(self, *exc_info):
        print(f'{self.file_count} files extracted')

コマンドラインインターフェイス

Added in version 3.4.

tarfile モジュールは、tar アーカイブを操作するための単純なコマンドラインインターフェースを提供します。

新しい tar アーカイブを作成するには、-c オプションの直後にアーカイブ名を指定し、その後に格納するファイル名を並べます。

$ python -m tarfile -c monty.tar  spam.txt eggs.txt

ディレクトリを渡すこともできます:

$ python -m tarfile -c monty.tar life-of-brian_1979/

tar アーカイブをカレントディレクトリに展開したい場合、-e オプションを使用してください:

$ python -m tarfile -e monty.tar

ディレクトリ名を渡すことで tar アーカイブを別のディレクトリに取り出すこともできます:

$ python -m tarfile -e monty.tar  other-dir/

tar アーカイブ内のファイル一覧を表示するには -l を使用してください:

$ python -m tarfile -l monty.tar

コマンドラインオプション

-l <tarfile>
--list <tarfile>

tarfile 内のファイル一覧を表示します。

-c <tarfile> <source1> ... <sourceN>
--create <tarfile> <source1> ... <sourceN>

ソースファイルから tarfile を作成します。

-e <tarfile> [<output_dir>]
--extract <tarfile> [<output_dir>]

output_dir が指定されていない場合、カレントディレクトリに tarfile を展開します。

-t <tarfile>
--test <tarfile>

tarfile が有効かどうか調べます。

-v, --verbose

詳細も出力します。

--filter <filtername>

--extract の filter を指定します。 詳しくは 展開フィルター を参照してください。 文字列の名前 (fully_trusted、tar、data) だけを受け付けます。

使用例

読み取りの例

tar アーカイブから現在のディレクトリにすべて抽出する方法:

import tarfile
tar = tarfile.open("sample.tar.gz")
tar.extractall(filter='data')
tar.close()

tar アーカイブの一部を、リストの代わりにジェネレーター関数を利用して TarFile.extractall() で展開する方法:

import os
import tarfile

def py_files(members):
    for tarinfo in members:
        if os.path.splitext(tarinfo.name)[1] == ".py":
            yield tarinfo

tar = tarfile.open("sample.tar.gz")
tar.extractall(members=py_files(tar))
tar.close()

gzip 圧縮された tar アーカイブを読み取り、メンバーの情報の一部を表示する方法。

import tarfile
tar = tarfile.open("sample.tar.gz", "r:gz")
for tarinfo in tar:
    print(tarinfo.name, "is", tarinfo.size, "bytes in size and is ", end="")
    if tarinfo.isreg():
        print("a regular file.")
    elif tarinfo.isdir():
        print("a directory.")
    else:
        print("something else.")
tar.close()

書き込みの例

非圧縮 tar アーカイブをファイル名のリストから作成する方法:

import tarfile
tar = tarfile.open("sample.tar", "w")
for name in ["foo", "bar", "quux"]:
    tar.add(name)
tar.close()

with 文を利用した同じ例:

import tarfile
with tarfile.open("sample.tar", "w") as tar:
    for name in ["foo", "bar", "quux"]:
        tar.add(name)

How to create and write an archive to stdout using sys.stdout.buffer in the fileobj parameter in TarFile.add():

import sys
import tarfile
with tarfile.open("sample.tar.gz", "w|gz", fileobj=sys.stdout.buffer) as tar:
    for name in ["foo", "bar", "quux"]:
        tar.add(name)

TarFile.add() 関数の filter 引数を利用してユーザー情報をリセットしながらアーカイブを作成する方法:

import tarfile
def reset(tarinfo):
    tarinfo.uid = tarinfo.gid = 0
    tarinfo.uname = tarinfo.gname = "root"
    return tarinfo
tar = tarfile.open("sample.tar.gz", "w:gz")
tar.add("foo", filter=reset)
tar.close()

サポートしている tar フォーマット

tarfile モジュールで作成できる tar 形式は 3 つあります:

  • POSIX.1-1988 ustar format (USTAR_FORMAT). ファイル名の長さは256文字までで、リンク名の長さは100文字までです。最大のファイルサイズは8GiBです。このフォーマットは古くて制限が多いですが、広くサポートされています。

  • GNU tar 形式 (GNU_FORMAT)。 長いファイル名とリンク名、8 GiB を超えるファイル、スパースファイルをサポートします。 GNU/Linux システムでは事実上の標準です。 tarfile は長い名前のための GNU tar 拡張を完全にサポートしますが、スパースファイルは読み取りのみサポートします。

  • POSIX.1-2001 pax 形式 (PAX_FORMAT)。 最も柔軟で、事実上制限のない形式です。 長いファイル名とリンク名、大きなファイルをサポートし、移植性のある方法でパス名を格納します。 GNU tar、bsdtar/libarchive、star を含む現代の tar 実装は、拡張された pax の機能を完全にサポートします。 古いライブラリや保守されていないライブラリにはサポートしないものもありますが、pax アーカイブを、広くサポートされている ustar 形式として扱うはずです。 現在、新しいアーカイブのデフォルトの形式です。

    既存の ustar 形式を拡張し、そのままでは格納できない情報を追加のヘッダーに格納します。 pax ヘッダーには 2 種類あります。 拡張ヘッダーは直後のファイルヘッダーにのみ影響し、グローバルヘッダーはアーカイブ全体に有効で、後続のすべてのファイルに影響します。 pax ヘッダーのデータは、移植性のためすべて UTF-8 でエンコードされます。

他にも、読み込みのみサポートしている tar フォーマットがいくつかあります:

  • ancient V7 フォーマット。これは Unix 7th Edition から存在する、最初の tar フォーマットです。通常のファイルとディレクトリのみ保存します。名前は 100 文字を超えてはならず、ユーザー/グループ名に関する情報は保存されません。いくつかのアーカイブは、フィールドが ASCII でない文字を含む場合に、ヘッダーのチェックサムの計算を誤ります。

  • SunOS tar 拡張フォーマット。POSIX.1-2001 pax フォーマットの亜流ですが、互換性がありません。

Unicode に関する問題

tar 形式は、ファイルシステムの情報の保持を主な目的として、テープドライブにバックアップを作成するために考案されました。 現在、tar アーカイブはファイルの配布やネットワーク上でのアーカイブの交換によく使われます。 元の形式 (ほかのすべての形式の基になったもの) の問題の 1 つは、異なる文字エンコーディングを扱う概念がないことです。 例えば UTF-8 のシステムで作成された通常の tar アーカイブに非 ASCII 文字が含まれていると、Latin-1 のシステムでは正しく読み取れません。 ファイル名、リンク名、ユーザー名、グループ名などのテキストのメタデータが文字化けして見えます。 残念ながら、アーカイブのエンコーディングを自動検出する方法はありません。 pax 形式はこの問題を解決するために設計され、非 ASCII のメタデータを共通の文字エンコーディング UTF-8 で格納します。

tarfile での文字変換の詳細は、TarFile クラスの encoding キーワード引数と errors キーワード引数で制御します。

encoding はアーカイブのメタデータに使用する文字エンコーディングを指定します。デフォルト値は sys.getfilesystemencoding() で、フォールバックとして 'ascii' が使用されます。アーカイブの読み書き時に、メタデータはそれぞれデコードまたはエンコードしなければなりません。encoding に適切な値が設定されていない場合、その変換は失敗することがあります。

errors 引数は、変換できない文字の扱い方を指定します。 指定できる値は エラーハンドラ 節を参照してください。 デフォルトは 'surrogateescape' で、Python のファイルシステム操作でも使われます。 ファイル名、コマンドライン引数、および環境変数 を参照してください。

デフォルトの PAX_FORMAT アーカイブでは、メタデータはすべて UTF-8 で格納されるため、encoding は通常指定する必要はありません。encoding は、まれにある、バイナリの pax ヘッダーがデコードされた場合、あるいはサロゲート文字を含む文字列が格納されていた場合に使用されます。