tarfile --- tar アーカイブファイルの読み書き¶
ソースコード: Lib/tarfile.py
tarfile モジュールは、gzip、bz2、および lzma 圧縮されたものを含む、tar アーカイブを読み書きできます。.zip ファイルの読み書きには zipfile モジュールか、あるいは shutil の高水準関数を使用してください。
いくつかの事実と形態:
POSIX.1-1988 (ustar) フォーマットの読み書きをサポートしています。
longname および longlink 拡張を含む GNU tar フォーマットの読み書きをサポートしています。スパースファイルの復元を含む sparse 拡張は読み込みのみサポートしています。
POSIX.1-2001 (pax) フォーマットの読み書きをサポートしています。
ディレクトリ、通常ファイル、ハードリンク、シンボリックリンク、FIFO、キャラクターデバイス、ブロックデバイスを扱えます。 また、タイムスタンプ、アクセス権、所有者などのファイル情報を取得・復元できます。
バージョン 3.3 で変更: lzma 圧縮をサポートしました。
バージョン 3.12 で変更: Archives are extracted using a filter, which makes it possible to either limit surprising/dangerous features, or to acknowledge that they are expected and the archive is fully trusted. By default, archives are fully trusted, but this default is deprecated and slated to change in Python 3.14.
- tarfile.open(name=None, mode='r', fileobj=None, bufsize=10240, **kwargs)¶
パス名 name の
TarFileオブジェクトを返します。TarFileオブジェクトと、利用できるキーワード引数に関する詳細な情報については、TarFile オブジェクト 節を参照してください。mode は
'filemode[:compression]'の形式をとる文字列でなければなりません。デフォルトの値は'r'です。以下に mode のとりうる組み合わせすべてを示します:mode
action
'r'or'r:*'圧縮方法に関して透過的に、読み込み用にオープンします (推奨)。
'r:'非圧縮のアーカイブだけを読み込み用に開きます。
'r:gz'gzip 圧縮で読み込み用にオープンします。
'r:bz2'bzip2 圧縮で読み込み用にオープンします。
'r:xz'lzma 圧縮で読み込み用にオープンします。
'x'or'x:'圧縮せずに tarfile を排他的に作成します。tarfile が既存の場合
FileExistsError例外を送出します。'x:gz'gzip 圧縮で tarfile を作成します。tarfile が既存の場合
FileExistsError例外を送出します。'x:bz2'bzip2 圧縮で tarfile を作成します。tarfile が既存の場合
FileExistsError例外を送出します。'x:xz'lzma 圧縮で tarfile を作成します。tarfile が既存の場合
FileExistsError例外を送出します。'a'or'a:'非圧縮で追記用にオープンします。ファイルが存在しない場合は新たに作成されます。
'w'or'w:'非圧縮で書き込み用にオープンします。
'w:gz'gzip 圧縮で書き込み用にオープンします。
'w:bz2'bzip2 圧縮で書き込み用にオープンします。
'w:xz'lzma 圧縮で書き込み用にオープンします。
'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 (デフォルトは9) を受け付けます。For modes
'w:xz'and'x:xz',tarfile.open()accepts the keyword argument preset to specify the compression level of the file.特別な用途のため、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 を読み込み用にオープンします。
'w|'非圧縮の stream を書き込み用にオープンします。
'w|gz'gzip 圧縮の stream を書き込み用にオープンします。
'w|bz2'bzip2 圧縮の stream を書き込み用にオープンします。
'w|xz'lzma 圧縮の stream を書き込み用にオープンします。
バージョン 3.5 で変更:
'x'(排他的作成) モードが追加されました。バージョン 3.6 で変更: name パラメタが path-like object を受け付けるようになりました。
バージョン 3.12 で変更: compresslevel キーワード引数がストリームにも使えるようになりました。
- class tarfile.TarFile
tar アーカイブを読み書きするためのクラスです。このクラスを直接使わないこと: 代わりに
tarfile.open()を使ってください。TarFile オブジェクト を参照してください。
- tarfile.is_tarfile(name)¶
もし name が tar アーカイブファイルであり、
tarfileモジュールで読み込める場合にTrueを返します。 name はstr、ファイルまたは file-like オブジェクトです。バージョン 3.9 で変更: ファイルおよびファイルライクオブジェクトをサポートしました。
tarfile モジュールは以下の例外を定義しています:
- exception tarfile.TarError¶
すべての
tarfile例外のための基本クラスです。
- exception tarfile.ReadError¶
tar アーカイブがオープンされた時、
tarfileモジュールで操作できないか、あるいは何か無効であるとき送出されます。
- exception tarfile.CompressionError¶
圧縮方法がサポートされていないか、あるいはデータを正しくデコードできない時に送出されます。
- exception tarfile.ExtractError¶
TarFile.extract()を使った時に 致命的でない エラーに対して送出されます。ただしTarFile.errorlevel== 2の場合に限ります。
- exception tarfile.HeaderError¶
TarInfo.frombuf()メソッドが取得したバッファーが不正だったときに送出されます。
- exception tarfile.AbsolutePathError¶
絶対パスを持つメンバーの展開を拒否するために送出されます。
- exception tarfile.OutsideDestinationError¶
展開先ディレクトリの外部へのメンバーの展開を拒否するために送出されます。
- exception tarfile.SpecialFileError¶
特殊ファイル (デバイスやパイプなど) の展開を拒否するために送出されます。
- exception tarfile.AbsoluteLinkError¶
絶対パスを指すシンボリックリンクの展開を拒否するために送出されます。
- exception tarfile.LinkOutsideDestinationError¶
展開先ディレクトリの外部を指すシンボリックリンクの展開を拒否するために送出されます。
- exception tarfile.LinkFallbackError¶
Raised to refuse emulating a link (hard or symbolic) by extracting another archive member, when that member would be rejected by the filter location. The exception that was raised to reject the replacement member is available as
BaseException.__context__.Added in version 3.13.4.
モジュールレベルで以下の定数が利用できます。
- tarfile.ENCODING¶
既定の文字エンコーディング。Windows では
'utf-8'、それ以外ではsys.getfilesystemencoding()の返り値です。
以下の各定数は、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.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 の名前付きの値が使用されます。The filter argument specifies how
membersare modified or rejected before extraction. See 展開フィルター for details. It is recommended to set this explicitly depending on which tar features you need to support.警告
Never extract archives from untrusted sources without prior inspection. It is possible that files are created outside of path, e.g. members that have absolute filenames starting with
"/"or filenames with two dots"..".Set
filter='data'to prevent the most dangerous security issues, and read the 展開フィルター section for details.バージョン 3.5 で変更: numeric_owner 引数が追加されました。
バージョン 3.6 で変更: path パラメタが path-like object を受け付けるようになりました。
バージョン 3.12 で変更: filter パラメータが追加されました。
- 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()メソッドの利用を考慮するべきです。警告
See the warning for
extractall().Set
filter='data'to prevent the most dangerous security issues, and read the 展開フィルター section for details.バージョン 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 引数と異なり、文字列の名前は指定できません。If
extraction_filterisNone(the default), calling an extraction method without a filter argument will raise aDeprecationWarning, and fall back to thefully_trustedfilter, whose dangerous behavior matches previous versions of Python.In Python 3.14+, leaving
extraction_filter=Nonewill cause extraction methods to use thedatafilter by default.The attribute may be set on instances or overridden in subclasses. It also is possible to set it on the
TarFileclass itself to set a global default, although, since it affects all uses of tarfile, it is best practice to only do so in top-level applications orsite configuration. To set a global default this way, a filter function needs to be wrapped in@staticmethodto prevent injection of aselfargument.
- 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 を受け付けるようになりました。
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()は代わりの文字列を表示します。
- 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.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.sparse¶
スパースなメンバーの情報。
- 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 オブジェクトは便利な照会用のメソッドもいくつか提供しています:
展開フィルター¶
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を使います。If that is also
None(the default), raise aDeprecationWarning, and fall back to the'fully_trusted'filter, whose dangerous behavior matches previous versions of Python.In Python 3.14, the
'data'filter will become the default instead. It's possible to switch earlier; seeTarFile.extraction_filter.展開するメンバーごとに呼び出される、呼び出し可能オブジェクト。 メンバーを表す 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を送出します。Normalize filenames (
TarInfo.name) that contain..components usingos.path.normpath(). Note that this removes internal..components, which may change the meaning of the name if it traverses symbolic links.シンボリックリンクをたどった後の絶対パスが展開先の外部になるファイルは、展開を 拒否 します。
OutsideDestinationErrorを送出します。Refuse to extract links (hard or soft) whose name refers to the destination directory itself. This raises
OutsideDestinationError. Note that such files are refused even on platforms that do not support symbolic links.モードの上位ビット (setuid、setgid、sticky) と、グループおよびその他のユーザーの書き込みビット (
S_IWGRP|S_IWOTH) をクリアします。
変更後の
TarInfoメンバーを返します。バージョン 3.13.16 で変更: Filenames containing
..components are now normalized.
- tarfile.data_filter(member, path)¶
'data'フィルターを実装します。tar_filterの処理に加え、次の処理を行います:Normalize link targets (
TarInfo.linkname) usingos.path.normpath(). Note that this removes internal..components, which may change the meaning of the link if the path inTarInfo.linknametraverses symbolic links.絶対パスや展開先の外部を指すリンク (ハードリンクまたはシンボリックリンク) は、展開を 拒否 します。
AbsoluteLinkErrorまたはLinkOutsideDestinationErrorを送出します。シンボリックリンクをサポートしないプラットフォームでも、これらのファイルは拒否されます。
デバイスファイル (パイプを含む) の展開を 拒否 します。
SpecialFileErrorを送出します。ハードリンクを含む通常ファイルについては:
ほかのファイル (ディレクトリ) については、
modeをNoneに設定し、展開メソッドがアクセス権のビットを適用しないようにします。ユーザーとグループの情報 (
uid、gid、uname、gname) をNoneに設定し、展開メソッドがそれらを設定しないようにします。
変更後の
TarInfoメンバーを返します。バージョン 3.13.4 で変更: Link targets are now normalized.
フィルターのエラー¶
フィルターがファイルの展開を拒否すると、FilterError のサブクラスである適切な例外を送出します。
TarFile.errorlevel が 1 以上なら、これによって展開を中止します。
errorlevel=0 の場合は、エラーを記録してそのメンバーをスキップし、展開を続けます。
追加の検証のヒント¶
filter='data' を使っても、tarfile は信頼できないファイルを事前の検査なしに展開する用途には適していません。
特に、あらかじめ定義されたフィルターはサービス拒否攻撃を防ぎません。
利用者が追加の検査を行う必要があります。
検討すべき事項の一部を挙げます:
新しい一時ディレクトリに展開してください。 既存のリンクの悪用などを防げるほか、展開に失敗した後のクリーンアップも容易になります。Disallow symbolic links if you do not need the functionality.
信頼できないデータを扱う場合は、ディスク、メモリ、CPU の使用量を外部 (OS レベルなど) で制限してください。
Check filenames against an allow-list of characters (to filter out control characters, confusables, foreign path separators, etc.).
ファイル名の拡張子が想定どおりか確認してください (「クリックすると」実行されるファイルや、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
コマンドラインオプション¶
- -c <tarfile> <source1> ... <sourceN>¶
- --create <tarfile> <source1> ... <sourceN>¶
ソースファイルから tarfile を作成します。
- -e <tarfile> [<output_dir>]¶
- --extract <tarfile> [<output_dir>]¶
output_dir が指定されていない場合、カレントディレクトリに tarfile を展開します。
- -v, --verbose¶
詳細も出力します。
使用例¶
Reading examples¶
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()
Writing examples¶
非圧縮 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 モジュールは 3 種類の tar フォーマットを作成することができます:
POSIX.1-1988 ustar format (
USTAR_FORMAT). ファイル名の長さは256文字までで、リンク名の長さは100文字までです。最大のファイルサイズは8GiBです。このフォーマットは古くて制限が多いですが、広くサポートされています。GNU tar format (
GNU_FORMAT). 長いファイル名とリンク名、8GiBを超えるファイルやスパース(sparse)ファイルをサポートしています。これは GNU/Linux システムにおいてデファクト・スタンダードになっています。tarfileモジュールは長いファイル名を完全にサポートしています。 スパースファイルは読み込みのみサポートしています。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 ヘッダーがデコードされた場合、あるいはサロゲート文字を含む文字列が格納されていた場合に使用されます。