Содержание страницы
tarfile – Чтение и запись файлов tar-архивов¶tarfile – Read and write tar archive files
Исходный код: 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).
работает с директориями, обычными файлами, жёсткими ссылками, символическими ссылками, каналами FIFO, символьными и блочными устройствами, а также может получать и восстанавливать информацию о файлах, такую как временная метка, права доступа и владелец.
Изменено в версии 3.3: Добавлена поддержка сжатия lzma.
-
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, он используется вместо файлового объекта, открытого в бинарном режиме для имени. Предполагается, что он находится на позиции 0.
Для режимов
'w:gz','r:gz','w:bz2','r:bz2','x:gz','x:bz2',tarfile.open()принимает именованный аргумент compresslevel (по умолчанию9) для указания уровня сжатия файла.Для режимов
'w:xz'и'x:xz'tarfile.open()принимает именованный аргумент preset для указания уровня сжатия файла.Для специальных целей существует второй формат для mode:
'filemode|[compression]'.tarfile.open()вернёт объектTarFile, который обрабатывает данные как поток блоков. Поиск по файлу с произвольным доступом не выполняется. Если задан fileobj, это может быть любой объект с методамиread()илиwrite()(в зависимости от mode). bufsize задаёт размер блока; по умолчанию20 * 512байт. Используйте этот вариант в сочетании, например, сsys.stdin, сокетным файловым объектом или ленточным устройством. Однако такой объект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 принимает объект, подобный пути.
-
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.FilterError¶ Базовый класс для элементов, отклонённых фильтрами.
-
exception
tarfile.AbsolutePathError¶ Возникает при отказе извлекать элемент с абсолютным путём.
-
exception
tarfile.OutsideDestinationError¶ Возникает при отказе извлекать элемент за пределами целевого каталога.
-
exception
tarfile.SpecialFileError¶ Возникает при отказе извлекать специальный файл (например, устройство или канал).
-
exception
tarfile.AbsoluteLinkError¶ Возникает при отказе извлекать символическую ссылку с абсолютным путём.
-
exception
tarfile.LinkOutsideDestinationError¶ Возникает при отказе извлекать символическую ссылку, указывающую за пределы целевого каталога.
-
exception
tarfile.LinkFallbackError¶ Возникает при отказе эмулировать ссылку (жёсткую или символическую) путём извлечения другого элемента архива, если этот элемент был бы отклонён расположением фильтра. Исключение, вызванное для отклонения заменяющего элемента, доступно как
BaseException.__context__.Новое в версии 3.9.25 (не выпущена).
На уровне модуля доступны следующие константы:
-
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, базовый формат tar
Документация для файлов архивов tar, включая расширения GNU tar.
Объекты TarFile¶TarFile Objects
Объект TarFile предоставляет интерфейс к архиву tar. Архив tar представляет собой последовательность блоков. Элемент архива (хранимый файл) состоит из заголовочного блока, за которым следуют блоки данных. Файл можно сохранить в архив tar несколько раз. Каждый элемент архива представляется объектом TarInfo, подробнее см. Объекты TarInfo.
Объект TarFile можно использовать как контекстный менеджер в операторе with. Он будет автоматически закрыт по завершении блока. Обратите внимание: в случае исключения архив, открытый для записи, не будет финализирован; будет закрыт только внутренний файловый объект. Пример использования см. в разделе Примеры.
Новое в версии 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)¶ Все последующие аргументы необязательны и также могут быть доступны как атрибуты экземпляра.
name – это путь к архиву. name может быть объектом, подобным пути. Его можно опустить, если указан 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 определяют кодировку символов, используемую для чтения или записи архива, и способ обработки ошибок преобразования. Настройки по умолчанию подходят для большинства пользователей. Подробную информацию см. в разделе Проблемы Unicode.
Аргумент pax_headers – необязательный словарь строк, который будет добавлен как глобальный заголовок pax, если format равно
PAX_FORMAT.Изменено в версии 3.2: В качестве значения по умолчанию для аргумента errors используется
'surrogateescape'.Изменено в версии 3.5: Добавлен режим
'x'(эксклюзивное создание).Изменено в версии 3.6: Параметр name принимает объект, подобный пути.
-
classmethod
TarFile.open(...)¶ Альтернативный конструктор. Функция
tarfile.open()на самом деле является сокращением для этого метода класса.
-
TarFile.getmember(name)¶ Возвращает объект
TarInfoдля элемента name. Если 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()¶ Возвращает следующий элемент архива в виде объекта
TarInfo, когдаTarFileоткрыт для чтения. Если больше нет элементов, возвращаетNone.
-
TarFile.extractall(path=".", members=None, *, numeric_owner=False, filter=None)¶ Извлекает все элементы из архива в текущую рабочую директорию или в директорию path. Если задан необязательный параметр members, он должен быть подмножеством списка, возвращаемого
getmembers(). Сведения о директории (владелец, время изменения, права доступа) устанавливаются после извлечения всех элементов. Это сделано для обхода двух проблем: время изменения директории сбрасывается при каждом создании в ней файла, и если права директории не разрешают запись, извлечение в неё файлов завершится ошибкой.Если numeric_owner равно
True, для установки владельца и группы извлечённых файлов используются числовые uid и gid из tar-файла. В противном случае используются именованные значения из tar-файла.Аргумент filter, который был добавлен в Python 3.9.17, определяет, как
membersизменяются или отклоняются перед извлечением. См. Фильтры извлечения для подробностей. Рекомендуется явно задавать этот параметр в зависимости от того, какие возможности tar необходимо поддерживать.Предупреждение
Никогда не извлекайте архивы из ненадёжных источников без предварительной проверки. Возможно создание файлов за пределами path, например, элементов с абсолютными именами, начинающимися с
"/", или с именами, содержащими две точки"..".Установите
filter='data', чтобы предотвратить наиболее опасные проблемы безопасности, и прочитайте раздел Extraction filters для подробностей.Изменено в версии 3.5: Добавлен параметр numeric_owner.
Изменено в версии 3.6: Параметр path теперь принимает объект, подобный пути.
Изменено в версии 3.9.17: добавлен параметр filter.
-
TarFile.extract(member, path="", set_attrs=True, *, numeric_owner=False, filter=None)¶ Извлекает элемент из архива в текущую рабочую директорию, используя его полное имя. Информация о файле извлекается максимально точно. member может быть именем файла или объектом
TarInfo. Можно указать другую директорию с помощью path. path может быть объектом, подобным пути. Атрибуты файла (владелец, mtime, права доступа) устанавливаются, если set_attrs не равно false.Аргументы numeric_owner и filter такие же, как для
extractall().Примечание
Метод
extract()не решает ряд проблем извлечения. В большинстве случаев стоит рассмотреть использование методаextractall().Предупреждение
См. предупреждение для
extractall().Установите
filter='data', чтобы предотвратить наиболее опасные проблемы безопасности, и прочитайте раздел Extraction filters для подробностей.Изменено в версии 3.2: Добавлен параметр set_attrs.
Изменено в версии 3.5: Добавлен параметр numeric_owner.
Изменено в версии 3.6: Параметр path теперь принимает объект, подобный пути.
Изменено в версии 3.9.17: добавлен параметр filter.
-
TarFile.extractfile(member)¶ Извлекает элемент из архива в виде файлового объекта. member может быть именем файла или объектом
TarInfo. Если member – обычный файл или ссылка, возвращается объектio.BufferedReader. Для всех остальных существующих элементов возвращаетсяNone. Если member не найден в архиве, вызываетсяKeyError.Изменено в версии 3.3: Возвращается объект
io.BufferedReader.
-
TarFile.errorlevel: int¶ Если errorlevel равен
0, ошибки игнорируются при использованииTarFile.extract()иTarFile.extractall(). Тем не менее, они отображаются как сообщения об ошибках в отладочном выводе, когда debug больше 0. Если1(по умолчанию), все фатальные ошибки вызываются как исключенияOSErrorилиFilterError. Если2, все нефатальные ошибки также вызываются как исключенияTarError.Некоторые исключения, например, вызванные неправильными типами аргументов или повреждением данных, всегда вызываются.
Пользовательские фильтры извлечения должны вызывать
FilterErrorдля фатальных ошибок иExtractErrorдля нефатальных.Обратите внимание, что при возникновении исключения архив может быть извлечён частично. Ответственность за очистку лежит на пользователе.
-
TarFile.extraction_filter¶ Новое в версии 3.9.17.
Фильтр извлечения, используемый по умолчанию для аргумента filter методов
extract()иextractall().Атрибут может быть
Noneили вызываемым объектом. Строковые имена для этого атрибута не допускаются, в отличие от аргумента filter дляextract().Если
extraction_filterравенNone(значение по умолчанию), вызов метода извлечения без аргумента filter приведёт к использованию фильтраfully_trustedдля совместимости с предыдущими версиями Python.В Python 3.12+ оставление
extraction_filter=NoneвызоветDeprecationWarning.Начиная с 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: Добавлен параметр filter.
Изменено в версии 3.7: Рекурсия добавляет записи в отсортированном порядке.
-
TarFile.addfile(tarinfo, fileobj=None)¶ Добавляет объект
TarInfotarinfo в архив. Если указан fileobj, он должен быть двоичным файлом, из которого читаютсяtarinfo.sizeбайтов и добавляются в архив. Можно создавать объектыTarInfoнапрямую или с помощьюgettarinfo().
-
TarFile.gettarinfo(name=None, arcname=None, fileobj=None)¶ Создаёт объект
TarInfoиз результатаos.stat()или эквивалентного для существующего файла. Файл задаётся либо именем name, либо указывается как файловый объект fileobj с файловым дескриптором. name может быть объектом, подобным пути. Если задан, arcname указывает альтернативное имя файла в архиве; в противном случае имя берётся из атрибутаnameобъекта fileobj или из аргумента name. Имя должно быть текстовой строкой.Можно изменить некоторые атрибуты объекта
TarInfoперед его добавлением с помощьюaddfile(). Если файловый объект не является обычным файловым объектом, расположенным в начале файла, такие атрибуты, какsize, могут потребовать изменения. Это относится к таким объектам, какGzipFile. Атрибутnameтакже может быть изменён, и в этом случае arcname может быть фиктивной строкой.Изменено в версии 3.6: Параметр name принимает объект, подобный пути.
-
TarFile.close()¶ Закрывает
TarFile. В режиме записи в архив добавляются два завершающих нулевых блока.
-
TarFile.pax_headers¶ Словарь, содержащий пары ключ-значение глобальных заголовков pax.
Объекты TarInfo¶TarInfo Objects
Объект TarInfo представляет один элемент в TarFile. Помимо
хранения всех необходимых атрибутов файла (таких как тип, размер, время,
права доступа, владелец и т.д.), он предоставляет некоторые полезные методы для определения его типа.
Он не содержит сами данные файла.
Объекты TarInfo возвращаются методами TarFile:
getmember(), getmembers() и
gettarinfo().
Изменение объектов, возвращённых методами getmember() или
getmembers(), повлияет на все последующие
операции с архивом.
В случаях, когда это нежелательно, можно использовать copy.copy() или
вызвать метод replace(), чтобы создать изменённую копию за один шаг.
Некоторые атрибуты могут быть установлены в None, чтобы указать, что часть метаданных
не используется или неизвестна.
Разные методы TarInfo обрабатывают None по-разному:
Методы
extract()иextractall()будут игнорировать соответствующие метаданные, оставляя их установленными по умолчанию.addfile()завершится ошибкой.list()выведет строку-заполнитель.
Изменено в версии 3.9.17: добавлены replace() и обработка None.
-
classmethod
TarInfo.frombuf(buf, encoding, errors)¶ Создаёт и возвращает объект
TarInfoиз строкового буфера buf.Вызывает
HeaderError, если буфер некорректен.
-
classmethod
TarInfo.fromtarfile(tarfile)¶ Читает следующий элемент из объекта
TarFiletarfile и возвращает его в виде объекта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.9.17: может быть установлено в
Noneдляextract()иextractall(), в результате чего извлечение пропускает применение этого атрибута.
-
TarInfo.mode: int¶ Биты прав доступа, как для
os.chmod().Изменено в версии 3.9.17: может быть установлено в
Noneдляextract()иextractall(), в результате чего извлечение пропускает применение этого атрибута.
-
TarInfo.type¶ Тип файла. Обычно type – это одна из следующих констант:
REGTYPE,AREGTYPE,LNKTYPE,SYMTYPE,DIRTYPE,FIFOTYPE,CONTTYPE,CHRTYPE,BLKTYPE,GNUTYPE_SPARSE. Чтобы более удобно определить тип объектаTarInfo, используйте методыis*(), описанные ниже.
-
TarInfo.linkname: str¶ Имя целевого файла, которое присутствует только в объектах
TarInfoтиповLNKTYPEиSYMTYPE.Для символических ссылок (
SYMTYPE) значение linkname указывается относительно каталога, содержащего ссылку. Для жёстких ссылок (LNKTYPE) значение linkname указывается относительно корня архива.
-
TarInfo.uid: int¶ Идентификатор пользователя, который изначально сохранил этот элемент.
Изменено в версии 3.9.17: может быть установлено в
Noneдляextract()иextractall(), в результате чего извлечение пропускает применение этого атрибута.
-
TarInfo.gid: int¶ Идентификатор группы пользователя, который изначально сохранил этот элемент.
Изменено в версии 3.9.17: Может быть установлено в
Noneдляextract()иextractall(), в результате чего извлечение пропустит применение этого атрибута.
-
TarInfo.uname: str¶ Имя пользователя.
Изменено в версии 3.9.17: Может быть установлено в
Noneдляextract()иextractall(), в результате чего извлечение пропустит применение этого атрибута.
-
TarInfo.gname: str¶ Имя группы.
Изменено в версии 3.9.17: Может быть установлено в
Noneдляextract()иextractall(), в результате чего извлечение пропустит применение этого атрибута.
-
TarInfo.pax_headers: dict¶ Словарь, содержащий пары ключ-значение связанного расширенного заголовка pax.
-
TarInfo.replace(name=..., mtime=..., mode=..., linkname=..., -
uid=..., gid=..., uname=..., gname=..., -
deep=True) Новое в версии 3.9.17.
Возвращает новую копию объекта
TarInfoс указанными изменёнными атрибутами. Например, чтобы вернутьTarInfoс именем группы, установленным в'staff', используйте:new_tarinfo = old_tarinfo.replace(gname='staff')
По умолчанию создаётся глубокая копия. Если deep равен false, копия поверхностная, то есть
pax_headersи любые пользовательские атрибуты являются общими с исходным объектомTarInfo.
Объект TarInfo также предоставляет несколько удобных запросных методов:
Фильтры извлечения¶Extraction filters
Новое в версии 3.9.17.
Формат tar предназначен для сохранения всех деталей файловых систем UNIX-подобных ОС,
что делает его очень мощным.
К сожалению, эти возможности позволяют легко создавать tar-файлы, которые при извлечении
могут иметь непреднамеренные – а возможно и вредоносные – эффекты.
Например, извлечение tar-файла может перезаписать произвольные файлы различными
способами (например, с использованием абсолютных путей, компонентов пути .. или символических ссылок,
влияющих на последующие элементы).
В большинстве случаев полная функциональность не требуется. Поэтому tarfile поддерживает фильтры извлечения: механизм ограничения функциональности, что позволяет смягчить некоторые проблемы безопасности.
См. также
- PEP 706
Содержит дополнительную мотивацию и обоснование дизайна.
Аргумент filter для TarFile.extract() или extractall()
может быть:
строка
'fully_trusted': соблюдать все метаданные, указанные в архиве. Следует использовать, если пользователь полностью доверяет архиву или реализует собственную сложную проверку.строка
'tar': соблюдать большинство специфических для tar возможностей (т.е. возможностей файловых систем UNIX-подобных ОС), но блокировать те, которые могут быть неожиданными или вредоносными. Подробнее см.tar_filter().строка
'data': игнорировать или блокировать большинство специфических для UNIX-подобных файловых систем возможностей. Предназначен для извлечения кроссплатформенных архивов. Подробнее см.data_filter().None(по умолчанию): использоватьTarFile.extraction_filter.Если это также
None(значение по умолчанию), будет использован фильтр'fully_trusted'(для совместимости с более ранними версиями Python).В Python 3.12 значение по умолчанию будет выдавать
DeprecationWarning.В Python 3.14 фильтр
'data'станет фильтром по умолчанию. Переключиться можно раньше; см.TarFile.extraction_filter.Вызываемый объект, который будет вызываться для каждого извлекаемого элемента с объектом TarInfo, описывающим элемент и путь назначения, куда извлекается архив (т.е. один и тот же путь используется для всех элементов):
filter(/, member: TarInfo, path: str) -> TarInfo | None
Вызываемый объект вызывается непосредственно перед извлечением каждого элемента, поэтому он может учитывать текущее состояние диска. Он может:
вернуть объект
TarInfo, который будет использоваться вместо метаданных в архиве, иливернуть
None, в этом случае элемент будет пропущен, иливызвать исключение для прерывания операции или пропуска элемента, в зависимости от
errorlevel. Обратите внимание, что при прерывании извлеченияextractall()может оставить архив частично извлечённым. Он не пытается выполнить очистку.
Именованные фильтры по умолчанию¶Default named filters
Предопределённые именованные фильтры доступны как функции, поэтому их можно повторно использовать в пользовательских фильтрах:
-
tarfile.fully_trusted_filter(/, member, path)¶ Возвращает элемент без изменений.
Это реализует фильтр
'fully_trusted'.
-
tarfile.tar_filter(/, member, path)¶ Реализует фильтр
'tar'.Удаляет начальные слеши (
/иos.sep) из имён файлов.Отказывается извлекать файлы с абсолютными путями (если имя является абсолютным даже после удаления слешей, например
C:/fooв Windows). Это вызываетAbsolutePathError.Отказывается извлекать файлы, абсолютный путь которых (после разрешения симлинков) оказался бы за пределами целевой директории. Это вызывает
OutsideDestinationError.Очищает биты высоких режимов (setuid, setgid, sticky) и биты записи для группы и остальных (
S_IWOTH).
Возвращает изменённый элемент
TarInfo.
-
tarfile.data_filter(/, member, path)¶ Реализует фильтр
'data'. В дополнение к тому, что делаетtar_filter:Нормализует цели ссылок (
TarInfo.linkname) с помощьюos.path.normpath(). Обратите внимание, что это удаляет внутренние компоненты.., что может изменить смысл ссылки, если путь вTarInfo.linknameпроходит через символические ссылки.Отказывается извлекать ссылки (жёсткие или символические), которые указывают на абсолютные пути или ведут за пределы целевой директории.
Это вызывает
AbsoluteLinkErrorилиLinkOutsideDestinationError.Обратите внимание, что такие файлы отклоняются даже на платформах, не поддерживающих символические ссылки.
Отказывается извлекать файлы устройств (включая каналы). Это вызывает
SpecialFileError.Для обычных файлов, включая жёсткие ссылки:
Устанавливает права на чтение и запись для владельца (
S_IWUSR).Удаляет право на выполнение для группы и остальных (
S_IXOTH) если владелец не имеет его (S_IXUSR).
Для остальных файлов (каталогов) устанавливает
modeвNone, чтобы методы извлечения пропускали применение битов разрешений.Устанавливает информацию о пользователе и группе (
uid,gid,uname,gname) вNone, чтобы методы извлечения пропускали её установку.
Возвращает изменённый элемент
TarInfo.Изменено в версии 3.9.25 (не выпущена): Цели ссылок теперь нормализуются.
Ошибки фильтра¶Filter errors
Когда фильтр отказывается извлекать файл, он возбуждает соответствующее исключение, подкласс FilterError. Это прервёт извлечение, если TarFile.errorlevel равно 1 или больше. При errorlevel=0 ошибка будет зарегистрирована, а элемент будет пропущен, но извлечение продолжится.
Рекомендации по дополнительной проверке¶Hints for further verification
Даже с filter='data', tarfile не подходит для извлечения недоверенных файлов без предварительной проверки. Среди прочих проблем, предопределённые фильтры не предотвращают атаки типа «отказ в обслуживании». Пользователям следует проводить дополнительные проверки.
Вот неполный список аспектов, которые стоит учесть:
Извлекайте в
new temporary directory, чтобы предотвратить, например, использование существующих ссылок, и упростить очистку после неудачного извлечения.Запретите символические ссылки, если эта функциональность не требуется.
При работе с недоверенными данными используйте внешние (например, на уровне ОС) ограничения на использование диска, памяти и процессора.
Проверяет имена файлов по списку разрешённых символов (для фильтрации управляющих символов, омоглифов, разделителей пути из других систем и т.д.).
Проверяет, что имена файлов имеют ожидаемые расширения (чтобы предотвратить файлы, которые выполняются при «двойном клике», или файлы без расширения, такие как специальные имена устройств Windows).
Ограничивает количество извлечённых файлов, общий объём извлечённых данных, длину имён файлов (включая длину символических ссылок) и размер отдельных файлов.
Проверяет наличие файлов, которые будут затенены на файловых системах без учёта регистра.
Также обратите внимание:
Tar-файлы могут содержать несколько версий одного и того же файла. Ожидается, что более поздние версии перезапишут любые предыдущие. Эта возможность критически важна для обновления ленточных архивов, но может быть злонамеренно использована.
tarfile не защищает от проблем с «активными» данными, например, когда злоумышленник манипулирует целевым (или исходным) каталогом во время извлечения (или архивирования).
Поддержка старых версий Python¶Supporting older Python versions
Фильтры извлечения были добавлены в 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: # удалить, когда больше не нужно warn_the_user('Extracting may be unsafe; consider updating Python') my_tarfile.extractall()
Пример фильтра извлечения с состоянием¶Stateful extraction filter example
Хотя методы извлечения 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')
Интерфейс командной строки¶Command-Line Interface
Новое в версии 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
Параметры командной строки¶Command-line options
-
-c<tarfile> <source1> ... <sourceN>¶ -
--create<tarfile> <source1> ... <sourceN>¶ Создаёт tar-архив из исходных файлов.
-
-e<tarfile> [<output_dir>]¶ -
--extract<tarfile> [<output_dir>]¶ Извлекает tar-архив в текущий каталог, если output_dir не указан.
-
-v,--verbose¶ Подробный вывод.
-
--filter<filtername>¶ Указывает фильтр для
--extract. Подробнее см. Фильтры извлечения. Принимаются только строковые имена (то естьfully_trusted,tar, иdata).Новое в версии 3.9.17.
Примеры¶Examples
Как извлечь полный tar-архив в текущий рабочий каталог:
import tarfile
tar = tarfile.open("sample.tar.gz")
tar.extractall()
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)
Как прочитать tar-архив, сжатый gzip, и вывести информацию о некоторых элементах:
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()
Как создать архив и сбросить информацию о пользователе, используя параметр фильтр
в 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¶Supported tar formats
Существует три формата 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 символами.
Расширенный формат SunOS tar. Этот формат является вариантом формата POSIX.1-2001 pax, но несовместим с ним.
Проблемы Unicode¶Unicode issues
Формат 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 или когда хранятся строки с
суррогатными символами.