tarfile
— Чтение и запись архивных файлов tar¶
Источник: Lib/tarfile.py
Модуль tarfile
позволяет читать и записывать tar-архивы, включая те, которые используют сжатие gzip, bz2 и lzma. Используйте модуль zipfile
для чтения и записи файлов .zip
или функции более высокого уровня в shutil.
Некоторые факты и цифры:
читает и записывает сжатые архивы
gzip
,bz2
иlzma
, если соответствующие модули доступны.поддержка чтения/записи для формата POSIX.1-1988 (ustar).
Поддержка формата GNU tar для чтения/записи, включая расширения longname и longlink, поддержка всех вариантов расширения sparse, включая восстановление разреженных файлов, только для чтения.
поддержка чтения/записи для формата POSIX.1-2001 (pax).
Работает с каталогами, обычными файлами, жесткими ссылками, символическими ссылками, fifos, символьными и блочными устройствами и может получать и восстанавливать информацию о файлах, такую как временная метка, разрешения на доступ и владелец.
Изменено в версии 3.3: Добавлена поддержка сжатия lzma
.
Изменено в версии 3.12: Архивы извлекаются с помощью filter, что позволяет либо ограничить неожиданные/опасные функции, либо подтвердить, что они ожидаемы и архив полностью доверен. По умолчанию архивы являются полностью доверенными, но это значение устарело и будет изменено в Python 3.14.
- tarfile.open(name=None, mode='r', fileobj=None, bufsize=10240, **kwargs)¶
Возвращает объект
TarFile
для имени пути name. Подробную информацию об объектахTarFile
и допустимых аргументах в виде ключевых слов см. в разделе Объекты TarFile.mode должен быть строкой вида
'filemode[:compression]'
, по умолчанию он принимает значение'r'
. Здесь приведен полный список комбинаций режимов:режим
действие
'r' or 'r:*'
Открыть для чтения с прозрачным сжатием (рекомендуется).
'r:'
Открыт для чтения исключительно без сжатия.
'r:gz'
Открыт для чтения со сжатием gzip.
'r:bz2'
Открыт для чтения со сжатием bzip2.
'r:xz'
Открыть для чтения со сжатием lzma.
'x'
или'x:'
Создайте tar-файл исключительно без сжатия. Вызывает исключение
FileExistsError
, если он уже существует.'x:gz'
Создайте tar-файл с gzip-сжатием. Вызовите исключение
FileExistsError
, если он уже существует.'x:bz2'
Создайте tar-файл со сжатием bzip2. Вызовите исключение
FileExistsError
, если он уже существует.'x:xz'
Создайте tar-файл со сжатием lzma. Вызовите исключение
FileExistsError
, если он уже существует.'a' or 'a:'
Открыть для добавления без сжатия. Файл создается, если он не существует.
'w' or 'w:'
Открыт для записи без сжатия.
'w:gz'
Открыт для записи с gzip-сжатием.
'w:bz2'
Открыт для записи со сжатием bzip2.
'w:xz'
Открыт для записи в сжатом виде lzma.
Обратите внимание, что
'a:gz'
,'a:bz2'
или'a:xz'
невозможны. Если режим не подходит для открытия определенного (сжатого) файла для чтения, то будет выдан сигналReadError
. Чтобы избежать этого, используйте режим'r'
. Если метод сжатия не поддерживается, выдается сообщениеCompressionError
.Если указан fileobj, он используется как альтернатива file object, открытому в двоичном режиме для name. Предполагается, что он находится в позиции 0.
Для режимов
'w:gz'
,'x:gz'
,'w|gz'
,'w:bz2'
,'x:bz2'
,'w|bz2'
,tarfile.open()
принимается ключевой аргумент compresslevel (по умолчанию9
) для указания уровня сжатия файла.Для режимов
'w:xz'
и'x:xz'
,tarfile.open()
принимает аргумент ключевого слова preset для указания уровня сжатия файла.Для специальных целей существует второй формат для mode:
'filemode|[compression]'
.tarfile.open()
вернет объектTarFile
, который обрабатывает свои данные как поток блоков. Никакого случайного поиска в файле производиться не будет. Если задано, fileobj может быть любым объектом, имеющим методread()
илиwrite()
(в зависимости от режима), который работает с байтами. bufsize задает размер блока и по умолчанию равен20 * 512
байт. Используйте этот вариант в сочетании, например, сsys.stdin.buffer
, сокетом file object или ленточным устройством. Однако такой объектTarFile
ограничен тем, что не допускает произвольного доступа, см. Примеры. В настоящее время возможны следующие режимы:Режим
Действие
'r|*'
Открыть поток блоков tar для чтения с прозрачным сжатием.
'r|'
Открыть поток несжатых tar-блоков для чтения.
'r|gz'
Открыть для чтения поток, сжатый gzip.
'r|bz2'
Открыть для чтения поток, сжатый в формате bzip2.
'r|xz'
Открыть для чтения поток, сжатый по методу lzma.
'w|'
Открыть несжатый поток для записи.
'w|gz'
Открыть сжатый gzip поток для записи.
'w|bz2'
Открыть сжатый в bzip2 поток для записи.
'w|xz'
Открыть сжатый поток в формате lzma для записи.
Изменено в версии 3.5: Добавлен режим
'x'
(эксклюзивное создание).Изменено в версии 3.6: Параметр name принимает значение path-like object.
Изменено в версии 3.12: Ключевой аргумент compresslevel также работает для потоков.
- class tarfile.TarFile
Класс для чтения и записи tar-архивов. Не используйте этот класс напрямую: вместо него используйте
tarfile.open()
. См. Объекты TarFile.
- tarfile.is_tarfile(name)¶
Возвращает
True
, если name является файлом архива tar, который модульtarfile
может прочитать. name может бытьstr
, файлом или файлоподобным объектом.Изменено в версии 3.9: Поддержка файлов и файлоподобных объектов.
Модуль tarfile
определяет следующие исключения:
- exception tarfile.ReadError¶
Возникает при открытии tar-архива, который либо не может быть обработан модулем
tarfile
, либо каким-то образом является недействительным.
- exception tarfile.CompressionError¶
Возникает, когда метод сжатия не поддерживается или когда данные не могут быть декодированы должным образом.
- exception tarfile.StreamError¶
Повышается для ограничений, характерных для потокоподобных
TarFile
объектов.
- 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¶
Повышается при отказе от извлечения символической ссылки, указывающей за пределы целевого каталога.
Следующие константы доступны на уровне модуля:
- tarfile.ENCODING¶
Кодировка символов по умолчанию:
'utf-8'
в Windows, значение, возвращаемоеsys.getfilesystemencoding()
в противном случае.
Каждая из следующих констант определяет формат tar-архива, который может создать модуль tarfile
. Подробности см. в разделе Поддерживаемые форматы 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: Формат по умолчанию для новых архивов был изменен на
PAX_FORMAT
сGNU_FORMAT
.
См.также
- Модуль
zipfile
Документация стандартного модуля
zipfile
.- Операции архивирования
Документация по средствам архивации более высокого уровня, предоставляемым стандартным модулем
shutil
.- GNU tar manual, Basic Tar Format
Документация по архивным файлам tar, включая расширения GNU tar.
Объекты TarFile¶
Объект TarFile
предоставляет интерфейс для работы с tar-архивом. Архив tar представляет собой последовательность блоков. Член архива (сохраненный файл) состоит из блока заголовка, за которым следуют блоки данных. Файл можно хранить в tar-архиве несколько раз. Каждый член архива представлен объектом TarInfo
, подробнее см. в разделе Объекты TarInfo.
Объект TarFile
может быть использован в качестве менеджера контекста в операторе 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 - это имя пути к архиву. name может быть path-like object. Его можно опустить, если указан fileobj. В этом случае используется атрибут
name
файлового объекта, если он существует.mode - это либо
'r'
для чтения из существующего архива,'a'
для добавления данных в существующий файл,'w'
для создания нового файла, перезаписывающего существующий, либо'x'
для создания нового файла, только если он еще не существует.Если задан fileobj, то он используется для чтения или записи данных. Если это можно определить, то mode переопределяется режимом fileobj. fileobj будет использоваться с позиции 0.
Примечание
fileobj не закрыт, когда
TarFile
закрыт.format управляет форматом архива для записи. Он должен быть одной из констант
USTAR_FORMAT
,GNU_FORMAT
илиPAX_FORMAT
, которые определяются на уровне модуля. При чтении формат будет определяться автоматически, даже если в одном архиве присутствуют разные форматы.Аргумент tarinfo можно использовать для замены класса
TarInfo
, используемого по умолчанию, на другой.Если dereference имеет значение
False
, в архив добавляются символические и жесткие ссылки. Если значениеTrue
, добавьте в архив содержимое целевых файлов. Это не влияет на системы, не поддерживающие символические ссылки.Если ignore_zeros имеет значение
False
, считайте пустой блок концом архива. Если оно равноTrue
, пропускайте пустые (и недействительные) блоки и старайтесь получить как можно больше членов. Это полезно только для чтения конкатенированных или поврежденных архивов.Для параметра debug можно установить значение от
0
(нет отладочных сообщений) до3
(все отладочные сообщения). Сообщения записываются вsys.stderr
.errorlevel управляет тем, как обрабатываются ошибки извлечения, см.
the corresponding attribute
.Аргументы encoding и errors определяют кодировку символов, которая будет использоваться для чтения или записи архива, и способ обработки ошибок преобразования. Настройки по умолчанию подойдут большинству пользователей. Более подробная информация приведена в разделе Проблемы с юникодом.
Аргумент pax_headers - это необязательный словарь строк, которые будут добавлены в качестве глобального заголовка pax, если format имеет значение
PAX_FORMAT
.Если stream имеет значение
True
, то при чтении архива информация о файлах в архиве не кэшируется, что экономит память.Изменено в версии 3.2: Используйте
'surrogateescape'
в качестве значения по умолчанию для аргумента errors.Изменено в версии 3.5: Добавлен режим
'x'
(эксклюзивное создание).Изменено в версии 3.6: Параметр name принимает значение path-like object.
Изменено в версии 3.13: Добавьте параметр stream.
- classmethod TarFile.open(...)¶
Альтернативный конструктор. Функция
tarfile.open()
фактически является ярлыком для этого метода класса.
- TarFile.getmember(name)¶
Возвращает объект
TarInfo
для члена name. Если имя не найдено в архиве, возвращаетсяKeyError
.Примечание
Если член встречается в архиве более одного раза, его последняя встреча считается наиболее актуальной версией.
- TarFile.getmembers()¶
Возвращает члены архива в виде списка объектов
TarInfo
. Список имеет тот же порядок, что и члены в архиве.
- TarFile.getnames()¶
Возвращает члены в виде списка их имен. Он имеет тот же порядок, что и список, возвращаемый командой
getmembers()
.
- TarFile.list(verbose=True, *, members=None)¶
Выведите оглавление в
sys.stdout
. Если значение verbose равноFalse
, выводятся только имена членов. Если значение verbose равноTrue
, будет выведен вывод, аналогичный ls -l. Если задано необязательное значение members, оно должно быть подмножеством списка, возвращаемогоgetmembers()
.Изменено в версии 3.5: Добавлен параметр members.
- TarFile.next()¶
Возвращает следующий член архива в виде объекта
TarInfo
, когдаTarFile
открыт для чтения. ВернитеNone
, если больше ничего не доступно.
- TarFile.extractall(path='.', members=None, *, numeric_owner=False, filter=None)¶
Извлечь все члены из архива в текущий рабочий каталог или каталог path. Если указано необязательное значение members, оно должно быть подмножеством списка, возвращаемого
getmembers()
. Информация о каталоге, такая как владелец, время модификации и права доступа, устанавливается после извлечения всех членов. Это делается для решения двух проблем: Время модификации каталога сбрасывается каждый раз, когда в нем создается файл. И если права доступа к каталогу не разрешают запись, извлечение файлов в него будет неудачным.Если numeric_owner равно
True
, то для задания владельца/группы извлеченных файлов используются номера uid и gid из tarfile. В противном случае используются именованные значения из tar-файла.Аргумент фильтр определяет, как
members
будут изменены или отклонены перед извлечением. Подробности см. в разделе Фильтры для извлечения. Рекомендуется задавать этот параметр явно в зависимости от того, какие функции tar вам необходимо поддерживать.Предупреждение
Никогда не извлекайте архивы из ненадежных источников без предварительной проверки. Возможно, что файлы создаются вне path, например, члены с абсолютными именами, начинающимися с
"/"
, или имена с двумя точками".."
.Установите значение
filter='data'
, чтобы предотвратить наиболее опасные проблемы безопасности, и прочитайте раздел Фильтры для извлечения для получения подробной информации.Изменено в версии 3.5: Добавлен параметр numeric_owner.
Изменено в версии 3.6: Параметр path принимает значение path-like object.
Изменено в версии 3.12: Добавлен параметр фильтр.
- TarFile.extract(member, path='', set_attrs=True, *, numeric_owner=False, filter=None)¶
Извлеките член архива в текущий рабочий каталог, используя его полное имя. Информация о файле извлекается как можно точнее. member может быть именем файла или объектом
TarInfo
. Вы можете указать другой каталог с помощью path. path может быть объектом path-like object. Атрибуты файла (владелец, mtime, mode) устанавливаются, если только set_attrs не равно false.Аргументы numeric_owner и filter такие же, как и для
extractall()
.Примечание
Метод
extract()
не позволяет решить несколько проблем с извлечением. В большинстве случаев следует использовать методextractall()
.Предупреждение
См. предупреждение для
extractall()
.Установите значение
filter='data'
, чтобы предотвратить наиболее опасные проблемы безопасности, и прочитайте раздел Фильтры для извлечения для получения подробной информации.Изменено в версии 3.2: Добавлен параметр set_attrs.
Изменено в версии 3.5: Добавлен параметр numeric_owner.
Изменено в версии 3.6: Параметр path принимает значение path-like object.
Изменено в версии 3.12: Добавлен параметр фильтр.
- TarFile.extractfile(member)¶
Извлечение члена из архива в виде файлового объекта. member может быть именем файла или объектом
TarInfo
. Если член является обычным файлом или ссылкой, возвращается объектio.BufferedReader
. Для всех остальных существующих членов возвращаетсяNone
. Если член не встречается в архиве, возвращаетсяKeyError
.Изменено в версии 3.3: Возвращает объект
io.BufferedReader
.Изменено в версии 3.13: Возвращаемый объект
io.BufferedReader
имеет атрибутmode
, который всегда равен'rb'
.
- TarFile.errorlevel: int¶
Если errorlevel равен
0
, ошибки игнорируются при использованииTarFile.extract()
иTarFile.extractall()
. Тем не менее, они появляются в виде сообщений об ошибках в отладочном выводе, если debug больше 0. Если1
(по умолчанию), все фатальные ошибки выдаются как исключенияOSError
илиFilterError
. Если2
, то все нефатальные ошибки также выдаются как исключенияTarError
.Некоторые исключения, например, вызванные неправильными типами аргументов или повреждением данных, всегда вызываются.
Пользовательский extraction filters должен поднимать
FilterError
для фатальных ошибок иExtractError
для нефатальных.Обратите внимание, что при возникновении исключения архив может быть частично извлечен. Ответственность за очистку лежит на пользователе.
- TarFile.extraction_filter¶
Added in version 3.12.
Значение extraction filter используется по умолчанию для аргументов фильтра
extract()
иextractall()
.Атрибут может быть
None
или вызываемым. Строковые имена для этого атрибута не допускаются, в отличие от аргумента filter вextract()
.Если
extraction_filter
равенNone
(по умолчанию), вызов метода извлечения без аргумента фильтр вызовет ошибкуDeprecationWarning
и вернется к фильтруfully_trusted
, опасное поведение которого соответствует предыдущим версиям Python.В Python 3.14+, если оставить
extraction_filter=None
, методы извлечения будут по умолчанию использовать фильтрdata
.Атрибут может быть установлен для экземпляров или переопределен в подклассах. Также можно установить его на сам класс
TarFile
, чтобы задать глобальное значение по умолчанию, хотя, поскольку это влияет на все использования tarfile, лучше всего делать это только в приложениях верхнего уровня илиsite configuration
. Чтобы установить глобальное значение по умолчанию таким образом, функцию фильтрации нужно обернуть вstaticmethod()
, чтобы предотвратить введение аргументаself
.
- TarFile.add(name, arcname=None, recursive=True, *, filter=None)¶
Добавьте файл name в архив. name может быть файлом любого типа (каталог, fifo, символическая ссылка и т.д.). Если задано, arcname указывает альтернативное имя файла в архиве. По умолчанию каталоги добавляются рекурсивно. Этого можно избежать, установив для параметра recursive значение
False
. Рекурсия добавляет записи в отсортированном порядке. Если задан filter, то это должна быть функция, которая принимает аргументTarInfo
и возвращает измененный объектTarInfo
. Если вместо этого возвращаетсяNone
, то объектTarInfo
будет исключен из архива. Пример см. в разделе Примеры.Изменено в версии 3.2: Добавлен параметр фильтр.
Изменено в версии 3.7: Рекурсия добавляет записи в отсортированном порядке.
- TarFile.addfile(tarinfo, fileobj=None)¶
Добавляет в архив
TarInfo
объект tarinfo. Если tarinfo представляет собой обычный файл ненулевого размера, аргумент fileobj должен быть binary file, из него считываютсяtarinfo.size
байта и добавляются в архив. Вы можете создавать объектыTarInfo
напрямую или с помощьюgettarinfo()
.Изменено в версии 3.13: Для обычных файлов ненулевого размера необходимо указать fileobj.
- TarFile.gettarinfo(name=None, arcname=None, fileobj=None)¶
Создайте объект
TarInfo
из результата выполненияos.stat()
или эквивалентного действия над существующим файлом. Файл либо именуется name, либо указывается как file object fileobj с дескриптором файла. name может быть path-like object. Если задано, arcname указывает альтернативное имя файла в архиве, в противном случае имя берется из атрибутаname
fileobj или аргумента name. Имя должно быть текстовой строкой.Вы можете изменить некоторые атрибуты
TarInfo
перед его добавлением с помощьюaddfile()
. Если объект файла не является обычным файловым объектом, расположенным в начале файла, могут потребоваться изменения таких атрибутов, какsize
. Это относится к таким объектам, какGzipFile
. Атрибутname
также может быть изменен, и в этом случае arcname может быть фиктивной строкой.Изменено в версии 3.6: Параметр name принимает значение path-like object.
Объекты TarInfo¶
Объект TarInfo
представляет один член в TarFile
. Помимо хранения всех необходимых атрибутов файла (таких как тип файла, размер, время, права доступа, владелец и т. д.), он предоставляет несколько полезных методов для определения его типа. Он не содержит самих данных файла.
Объекты TarInfo
возвращаются методами TarFile
getmember()
, getmembers()
и gettarinfo()
.
Модификация объектов, возвращаемых методами getmember()
или getmembers()
, повлияет на все последующие операции с архивом. Для случаев, когда это нежелательно, можно использовать copy.copy()
или вызвать метод replace()
, чтобы создать измененную копию за один шаг.
Некоторые атрибуты могут быть установлены в None
, чтобы указать, что часть метаданных не используется или неизвестна. Различные методы TarInfo
по-разному обрабатывают None
:
Методы
extract()
илиextractall()
будут игнорировать соответствующие метаданные, оставляя их установленными по умолчанию.addfile()
не удастся.list()
выведет строку-заготовку.
- classmethod TarInfo.frombuf(buf, encoding, errors)¶
Создайте и верните объект
TarInfo
из строкового буфера buf.Вызывает
HeaderError
, если буфер недействителен.
- classmethod TarInfo.fromtarfile(tarfile)¶
Прочитайте следующий член из
TarFile
объекта tarfile и верните его какTarInfo
объект.
- TarInfo.tobuf(format=DEFAULT_FORMAT, encoding=ENCODING, errors='surrogateescape')¶
Создает строковый буфер из объекта
TarInfo
. Информацию об аргументах см. в конструкторе классаTarFile
.Изменено в версии 3.2: Используйте
'surrogateescape'
в качестве значения по умолчанию для аргумента errors.
Объект TarInfo
имеет следующие атрибуты открытых данных:
- TarInfo.mtime: int | float¶
Время последней модификации в секундах с момента epoch, как в
os.stat_result.st_mtime
.Изменено в версии 3.12: Может быть установлено значение
None
дляextract()
иextractall()
, в результате чего извлечение не будет применять этот атрибут.
- TarInfo.mode: int¶
Биты разрешения, как для
os.chmod()
.Изменено в версии 3.12: Может быть установлено значение
None
дляextract()
иextractall()
, в результате чего извлечение не будет применять этот атрибут.
- TarInfo.type¶
Тип файла. Тип обычно является одной из этих констант:
REGTYPE
,AREGTYPE
,LNKTYPE
,SYMTYPE
,DIRTYPE
,FIFOTYPE
,CONTTYPE
,CHRTYPE
,BLKTYPE
,GNUTYPE_SPARSE
. Для более удобного определения типа объектаTarInfo
используйте приведенные ниже методыis*()
.
- TarInfo.linkname: str¶
Имя целевого файла, которое присутствует только в объектах
TarInfo
типаLNKTYPE
иSYMTYPE
.Для символических ссылок (
SYMTYPE
) имя ссылки указывается относительно каталога, содержащего ссылку. Для жестких ссылок (LNKTYPE
) имя ссылки относительно корня архива.
- TarInfo.uid: int¶
Идентификатор пользователя, который первоначально сохранил этого участника.
Изменено в версии 3.12: Может быть установлено значение
None
дляextract()
иextractall()
, в результате чего извлечение не будет применять этот атрибут.
- TarInfo.gid: int¶
Идентификатор группы пользователя, который первоначально сохранил этого участника.
Изменено в версии 3.12: Может быть установлено значение
None
дляextract()
иextractall()
, в результате чего извлечение не будет применять этот атрибут.
- TarInfo.uname: str¶
Имя пользователя.
Изменено в версии 3.12: Может быть установлено значение
None
дляextract()
иextractall()
, в результате чего извлечение не будет применять этот атрибут.
- TarInfo.gname: str¶
Название группы.
Изменено в версии 3.12: Может быть установлено значение
None
дляextract()
иextractall()
, в результате чего извлечение не будет применять этот атрибут.
- TarInfo.sparse¶
Скудная информация о членах.
- TarInfo.pax_headers: dict¶
Словарь, содержащий пары ключ-значение связанного расширенного заголовка pax.
- TarInfo.replace(name=..., mtime=..., mode=..., linkname=..., uid=..., gid=..., uname=..., gname=..., deep=True)¶
Added in version 3.12.
Возвращает новую копию объекта
TarInfo
с измененными заданными атрибутами. Например, чтобы вернутьTarInfo
с именем группы, установленным в'staff'
, используйте:new_tarinfo = old_tarinfo.replace(gname='staff')
По умолчанию создается глубокая копия. Если значение deep равно false, копия будет неглубокой, т. е.
pax_headers
и все пользовательские атрибуты будут использоваться совместно с исходным объектомTarInfo
.
Объект TarInfo
также предоставляет несколько удобных методов запроса:
Фильтры для извлечения¶
Added in version 3.12.
Формат tar предназначен для передачи всех деталей UNIX-подобной файловой системы, что делает его очень мощным. К сожалению, эти возможности позволяют легко создавать tar-файлы, которые при извлечении приводят к непредусмотренным - и, возможно, вредоносным - последствиям. Например, при извлечении tar-файла можно перезаписать произвольные файлы различными способами (например, используя абсолютные пути, компоненты пути ..
или симлинки, которые влияют на последующие члены).
В большинстве случаев полная функциональность не нужна. Поэтому tarfile поддерживает фильтры извлечения: механизм, позволяющий ограничить функциональность и тем самым смягчить некоторые проблемы безопасности.
См.также
- PEP 706
Содержит дополнительную мотивацию и обоснование дизайна.
Аргумент фильтр для TarFile.extract()
или extractall()
может быть:
строка
'fully_trusted'
: Соблюдать все метаданные, указанные в архиве. Следует использовать, если пользователь полностью доверяет архиву или реализует собственную сложную проверку.строка
'tar'
: Разрешить большинство tar-специфических функций (т.е. функций UNIX-подобных файловых систем), но блокировать функции, которые с большой вероятностью могут оказаться неожиданными или вредоносными. Подробности см. в разделеtar_filter()
.строка
'data'
: Игнорировать или блокировать большинство функций, характерных для UNIX-подобных файловых систем. Предназначен для извлечения кроссплатформенных архивов данных. Подробности см. в разделеdata_filter()
.None
(по умолчанию): ИспользоватьTarFile.extraction_filter
.Если он также равен
None
(по умолчанию), вызовитеDeprecationWarning
и вернитесь к фильтру'fully_trusted'
, опасное поведение которого соответствует предыдущим версиям Python.В Python 3.14 фильтр
'data'
будет использоваться по умолчанию. Можно перейти и раньше; смотритеTarFile.extraction_filter
.Вызываемый объект, который будет вызываться для каждого извлеченного члена с TarInfo, описывающим член и путь назначения к месту извлечения архива (т.е. один и тот же путь используется для всех членов):
filter(member: TarInfo, path: str, /) -> TarInfo | None
Вызывается непосредственно перед извлечением каждого члена, чтобы учесть текущее состояние диска. Она может:
возвращает объект
TarInfo
, который будет использоваться вместо метаданных в архиве, иливозвращает
None
, в этом случае член будет пропущен, илиподнять исключение, чтобы прервать операцию или пропустить член, в зависимости от
errorlevel
. Обратите внимание, что при прерывании извлеченияextractall()
может оставить архив частично извлеченным. Он не пытается очистить архив.
Именованные фильтры по умолчанию¶
Предварительно созданные фильтры с именами доступны в виде функций, поэтому их можно повторно использовать в пользовательских фильтрах:
- tarfile.fully_trusted_filter(member, path)¶
Верните член без изменений.
Это реализует фильтр
'fully_trusted'
.
- tarfile.tar_filter(member, path)¶
Реализует фильтр
'tar'
.Удалите из имен файлов ведущие косые черты (
/
иos.sep
).Refuse для извлечения файлов с абсолютными путями (в случае, если имя является абсолютным даже после удаления косых черт, например,
C:/foo
в Windows). Это повышаетAbsolutePathError
.Refuse для извлечения файлов, абсолютный путь которых (после перехода по симлинкам) окажется за пределами места назначения. Это приводит к появлению
OutsideDestinationError
.Очистите биты высокого режима (setuid, setgid, sticky) и биты групповой/прочей записи (
S_IWGRP
|S_IWOTH
).
Возвращает измененный член
TarInfo
.
- tarfile.data_filter(member, path)¶
Реализует фильтр
'data'
. В дополнение к тому, что делаетtar_filter
:Refuse для извлечения ссылок (жестких или мягких), которые ссылаются на абсолютные пути, или тех, которые ссылаются за пределы пункта назначения.
При этом поднимается
AbsoluteLinkError
илиLinkOutsideDestinationError
.Обратите внимание, что такие файлы не принимаются даже на платформах, не поддерживающих символические ссылки.
Refuse для извлечения файлов устройств (включая трубы). Это повышает
SpecialFileError
.Для обычных файлов, включая жесткие ссылки:
Для других файлов (каталогов) установите
mode
вNone
, чтобы методы извлечения пропускали применение битов разрешения.Установите информацию о пользователях и группах (
uid
,gid
,uname
,gname
) в значениеNone
, чтобы методы извлечения пропускали ее установку.
Возвращает измененный член
TarInfo
.
Ошибки фильтрации¶
Когда фильтр отказывается извлекать файл, он поднимает соответствующее исключение, подкласс FilterError
. Это прервет извлечение, если TarFile.errorlevel
равно 1 или больше. При значении errorlevel=0
ошибка будет занесена в журнал, член будет пропущен, но извлечение продолжится.
Подсказки для дальнейшей проверки¶
Даже при значении filter='data'
tarfile не подходит для извлечения недоверенных файлов без предварительной проверки. Помимо прочего, предустановленные фильтры не предотвращают атаки типа «отказ в обслуживании». Пользователям следует выполнять дополнительные проверки.
Вот неполный список того, что нужно учесть:
Извлеките в
new temporary directory
, чтобы предотвратить, например, использование ранее существовавших ссылок и облегчить очистку после неудачного извлечения.При работе с недоверенными данными используйте внешние (например, на уровне ОС) ограничения на использование диска, памяти и процессора.
Проверка имен файлов на соответствие списку разрешенных символов (для отсеивания управляющих символов, путаницы, иностранных разделителей путей и т.д.).
Убедитесь, что имена файлов имеют ожидаемые расширения (не рекомендуется использовать файлы, которые выполняются при нажатии на них, или файлы без расширений, например имена специальных устройств Windows).
Ограничьте количество извлекаемых файлов, общий размер извлекаемых данных, длину имен файлов (включая длину симлинков) и размер отдельных файлов.
Проверьте наличие файлов, которые будут затенены в файловых системах с нечувствительным регистром.
Также обратите внимание на то, что:
Файлы Tar могут содержать несколько версий одного и того же файла. Предполагается, что более поздние версии будут перезаписывать все более ранние. Эта функция очень важна для обновления ленточных архивов, но может быть использована с целью злоупотребления.
tarfile не защищает от проблем с «живыми» данными, например, от действий злоумышленника, который вмешивается в каталог назначения (или источника) во время извлечения (или архивирования).
Поддержка старых версий Python¶
Фильтры извлечения были добавлены в Python 3.12, но могут быть перенесены в более ранние версии в виде обновлений безопасности. Чтобы проверить, доступна ли функция, используйте, например, 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: # remove this when no longer needed 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>¶
Создайте tar-файл из исходных файлов.
- -e <tarfile> [<output_dir>]¶
- --extract <tarfile> [<output_dir>]¶
Распаковать tarfile в текущий каталог, если output_dir не указан.
- -v, --verbose¶
Подробный вывод.
- --filter <filtername>¶
Определяет фильтр для
--extract
. Подробности см. в разделе Фильтры для извлечения. Принимаются только строковые имена (то есть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()
Как создать несжатый 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)
Как прочитать сжатый 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()
Как создать архив и сбросить информацию о пользователе с помощью параметра filter в TarFile.add()
:
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¶
Существует три формата tar, которые можно создать с помощью модуля tarfile
:
Формат POSIX.1-1988 ustar (
USTAR_FORMAT
). Он поддерживает имена файлов длиной максимум 256 символов и имена ссылок длиной до 100 символов. Максимальный размер файла - 8 Гб. Это старый и ограниченный, но широко поддерживаемый формат.Формат GNU tar (
GNU_FORMAT
). Поддерживает длинные имена файлов и имена ссылок, файлы размером более 8 Гб и разреженные файлы. Является стандартом де-факто в системах GNU/Linux.tarfile
полностью поддерживает расширения GNU tar для длинных имен, поддержка разреженных файлов доступна только для чтения.Формат POSIX.1-2001 pax (
PAX_FORMAT
). Это самый гибкий формат, практически не имеющий ограничений. Он поддерживает длинные имена файлов и ссылок, большие файлы и переносимо хранит имена путей. Современные реализации tar, включая GNU tar, bsdtar/libarchive и star, полностью поддерживают расширенные возможности pax; некоторые старые или не поддерживаемые библиотеки могут этого не делать, но должны обращаться с архивами pax так, как если бы они были в универсально поддерживаемом формате ustar. Это текущий формат по умолчанию для новых архивов.Он расширяет существующий формат ustar дополнительными заголовками для информации, которая не может быть сохранена иным способом. Существует два вида заголовков pax: Расширенные заголовки влияют только на заголовок последующего файла, глобальные заголовки действительны для всего архива и влияют на все последующие файлы. Все данные в заголовке pax кодируются в UTF-8 для удобства переноса.
Есть еще несколько вариантов формата tar, которые можно прочитать, но нельзя создать:
Древний формат V7. Это первый формат tar из Unix Seventh Edition, хранящий только обычные файлы и каталоги. Имена не должны быть длиннее 100 символов, нет информации об именах пользователей/групп. В некоторых архивах неправильно подсчитываются контрольные суммы заголовков в случае полей, содержащих не ASCII-символы.
Расширенный формат tar для SunOS. Этот формат является вариантом формата POSIX.1-2001 pax, но не является совместимым.
Проблемы с юникодом¶
Изначально формат tar был задуман для создания резервных копий на ленточных накопителях с основным упором на сохранение информации о файловой системе. В настоящее время tar-архивы широко используются для распространения файлов и обмена архивами по сети. Одной из проблем оригинального формата (на котором основаны все остальные форматы) является отсутствие концепции поддержки различных кодировок символов. Например, обычный архив tar, созданный в системе UTF-8, не может быть корректно прочитан в системе Latin-1, если он содержит символы, отличные от ASCII. Текстовые метаданные (например, имена файлов, имена ссылок, имена пользователей/групп) будут выглядеть поврежденными. К сожалению, не существует способа автоматического определения кодировки архива. Формат pax был разработан для решения этой проблемы. Он хранит метаданные, отличные от ASCII, используя универсальную кодировку UTF-8.
Детали преобразования символов в tarfile
контролируются аргументами encoding и errors класса TarFile
.
encoding определяет кодировку символов, которую следует использовать для метаданных в архиве. По умолчанию используется значение sys.getfilesystemencoding()
или 'ascii'
в качестве запасного варианта. В зависимости от того, читается или записывается архив, метаданные должны быть либо декодированы, либо закодированы. Если значение encoding не задано должным образом, преобразование может завершиться неудачей.
Аргумент errors определяет, как будут обрабатываться символы, которые не могут быть преобразованы. Возможные значения перечислены в разделе Обработчики ошибок. По умолчанию используется схема 'surrogateescape'
, которую Python также использует для вызовов файловой системы, см. раздел Имена файлов, аргументы командной строки и переменные среды.
Для архивов PAX_FORMAT
(по умолчанию) encoding обычно не требуется, поскольку все метаданные хранятся с использованием UTF-8. encoding используется только в редких случаях, когда декодируются двоичные заголовки pax или когда хранятся строки с суррогатными символами.