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).
- обрабатывает каталоги, обычные файлы, жёсткие ссылки, символьные ссылки, fifo, символьные и блочные устройства и может получать и восстанавливать информацию о файлах, такие как метка времени, разрешения доступа и владелец.
Изменено в версии 3.3: Добавлена поддержка сжатия lzma.
-
tarfile.open(name=None, mode='r', fileobj=None, bufsize=10240, **kwargs) -
Возвращает объект
TarFileдля пути name. Для получения подробной информации об объектахTarFileи разрешенных ключевых аргументах, см. Объекты TarFile.mode должен быть строкой вида
'filemode[:compression]', по умолчанию'r'. Вот полный список комбинаций режимов:mode
действие
'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'невозможны. Если mode не подходит для открытия определенного (сжатого) файла для чтения, возникаетReadError. Используйте mode'r'для предотвращения этого. Если метод сжатия не поддерживается, возникаетCompressionError.Если fileobj указан, он используется как альтернатива объекту файла, открытому в двоичном режиме для name. Он предполагается, что находится в позиции 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.TarError -
Базовый класс для всех исключений модуля
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 -
Базовый класс для членов отклоненных фильтрами.
-
tarinfo -
Информация о члене, который фильтр отказался извлечь, как TarInfo.
-
-
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.
См. также
-
Modulezipfile -
Документация стандартного модуля
zipfile. - Операции архивирования
-
Документация по средствам архивирования высокого уровня, предоставляемых стандартным модулем
shutil. - Руководство GNU tar, Основной формат Tar
-
Документация для файлов архивов tar, включая расширения GNU tar.
Объекты TarFile
Объект 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: Используйте
'surrogateescape'в качестве значения по умолчанию для аргумента errors.Изменено в версии 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.10.12, определяет, как
membersизменяются или отклоняются перед извлечением. Подробности см. в разделе Фильтры извлечения. Рекомендуется явно устанавливать это значение в зависимости от тех функций tar, которые вам нужны.Предупреждение
Никогда не извлекайте архивы из ненадежных источников без предварительного проверки. Возможно, файлы создаются вне path, например, члены с абсолютными именами, начинающимися с
"/"или именами с двумя точками"..".Установите
filter='data'для предотвращения наиболее опасных проблем безопасности и прочитайте раздел Фильтры извлечения для получения подробностей.Изменено в версии 3.5: Добавлен параметр numeric_owner.
Изменено в версии 3.6: Параметр path принимает объект-путь.
Изменено в версии 3.10.12: Добавлен параметр filter.
-
TarFile.extract(member, path='', set_attrs=True, *, numeric_owner=False, filter=None) -
Извлечь член из архива в текущий рабочий каталог, используя его полное имя. Его информация о файле извлекается максимально точно. member может быть именем файла или объектом
TarInfo. Можно указать другой каталог, используя path. path может быть объектом, подобным пути. Атрибуты файла (владелец, время последнего изменения, режим) устанавливаются, если set_attrs не равно false.Аргументы numeric_owner и filter такие же, как и для
extractall().Примечание
Метод
extract()не обрабатывает несколько проблем с извлечением. В большинстве случаев следует использовать методextractall().Предупреждение
См. предупреждение для
extractall().Установите
filter='data'для предотвращения наиболее опасных проблем с безопасностью и ознакомьтесь с разделом «Фильтры извлечения» для получения подробной информации.Изменено в версии 3.2: Добавлен параметр set_attrs.
Изменено в версии 3.5: Добавлен параметр numeric_owner.
Изменено в версии 3.6: Параметр path принимает объект, подобный пути.
Изменено в версии 3.10.12: Добавлен параметр 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(по умолчанию), все ошибки fatal поднимаются как исключенияOSErrorилиFilterError. Если2, все некритические ошибки также поднимаются как исключенияTarError.Некоторые исключения, например, вызванные неправильными типами аргументов или повреждением данных, всегда поднимаются.
Пользовательские фильтры извлечения должны поднимать
FilterErrorдля ошибок fatal иExtractErrorдля некритических.Обратите внимание, что при возникновении исключения архив может быть частично извлечен. Пользователь отвечает за очистку.
-
TarFile.extraction_filter -
Новое в версии 3.10.12.
Фильтр извлечения, используемый по умолчанию для аргумента 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 представляет собой один член в TarFile. Помимо хранения всех необходимых атрибутов файла (например, типа файла, размера, времени, разрешений, владельца и т. д.), он предоставляет некоторые полезные методы для определения его типа. Он не содержит самих данных файла.
TarInfo объекты возвращаются методами TarFile getmember(), getmembers() и gettarinfo().
Изменение объектов, возвращаемых getmember() или getmembers(), повлияет на все последующие операции с архивом. В тех случаях, когда это нежелательно, вы можете использовать copy.copy() или вызвать метод replace(), чтобы создать изменённую копию в одном шаге.
Несколько атрибутов могут быть установлены в None для указания того, что часть метаданных не используется или неизвестна. Различные методы TarInfo обрабатывают None по-разному:
- Методы
extract()илиextractall()проигнорируют соответствующие метаданные, оставив их установленным в значение по умолчанию. -
addfile()завершится ошибкой. -
list()выведет строку-заполнитель.
Изменено в версии 3.10.12: Добавлены replace() и обработка None.
-
class tarfile.TarInfo(name='') -
Создаёт объект
TarInfo.
-
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: Используется
'surrogateescape'в качестве значения по умолчанию для аргумента errors.
Объект TarInfo имеет следующие публичные данные-атрибуты:
-
TarInfo.name: str -
Имя члена архива.
-
TarInfo.size: int -
Размер в байтах.
-
TarInfo.mtime: int | float -
Время последнего изменения в секундах с момента эпохи, как в
os.stat_result.st_mtime.Изменено в версии 3.10.12: Может быть установлено в
Noneдляextract()иextractall(), вызывая пропуск применения этого атрибута при извлечении.
-
TarInfo.mode: int -
Флаги разрешений, как для
os.chmod().Изменено в версии 3.10.12: Может быть установлено в
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.10.12: Может быть установлено в
Noneдляextract()иextractall(), вызывая пропуск применения этого атрибута при извлечении.
-
TarInfo.gid: int -
Идентификатор группы пользователя, который первоначально сохранил этот член.
Изменено в версии 3.10.12: Может быть установлено в
Noneдляextract()иextractall(), вызывая пропуск применения этого атрибута при извлечении.
-
TarInfo.uname: str -
Имя пользователя.
Изменено в версии 3.10.12: Может быть установлено в
Noneдляextract()иextractall(), вызывая пропуск применения этого атрибута при извлечении.
-
TarInfo.gname: str -
Имя группы.
Изменено в версии 3.10.12: Может быть установлено в
Noneдляextract()иextractall(), вызывая пропуск применения этого атрибута при извлечении.
-
TarInfo.pax_headers: dict -
Словарь, содержащий пары ключ-значение связанного расширенного заголовка pax.
-
TarInfo.replace(name=..., mtime=..., mode=..., linkname=..., -
uid=..., gid=..., uname=..., gname=..., -
deep=True) -
Новое в версии 3.10.12.
Возвращает новую копию объекта
TarInfoс изменёнными заданными атрибутами. Например, для возвратаTarInfoс именем группы, установленным в'staff', используйте:new_tarinfo = old_tarinfo.replace(gname='staff')
По умолчанию создаётся глубокая копия. Если deep ложно, создаётся поверхностная копия, т.е.
pax_headersи все пользовательские атрибуты совместно используются с исходным объектомTarInfo.
Объект TarInfo также предоставляет некоторые удобные методы запроса:
-
TarInfo.isfile() -
Возвращает
True, если объектTarinfoявляется обычным файлом.
-
TarInfo.isreg() -
То же, что и
isfile().
-
TarInfo.isdir() -
Возвращает
True, если это каталог.
-
TarInfo.issym() -
Возвращает
True, если это символическая ссылка.
-
TarInfo.islnk() -
Возвращает
True, если это жёсткая ссылка.
-
TarInfo.ischr() -
Возвращает
True, если это символьное устройство.
-
TarInfo.isblk() -
Возвращает
True, если это блочное устройство.
-
TarInfo.isfifo() -
Возвращает
True, если это FIFO.
-
TarInfo.isdev() -
Возвращает
True, если это символьное устройство, блочное устройство или FIFO.
Фильтры извлечения
Новое в версии 3.10.12.
Формат 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()может оставить архив частично извлеченным. Он не пытается произвести очистку.
- вернуть объект
Фильтры по умолчанию с именами
Определенные предварительно фильтры доступны как функции, поэтому их можно повторно использовать в пользовательских фильтрах:
-
tarfile.fully_trusted_filter(/, member, path) -
Возвращает member без изменений.
Реализует фильтр
'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:-
Отклонить извлечение ссылок (жёстких или мягких), которые ведут к абсолютным путям или путям за пределами назначения.
Это вызывает
AbsoluteLinkErrorилиLinkOutsideDestinationError.Обратите внимание, что такие файлы отклоняются даже на платформах, которые не поддерживают символические ссылки.
-
Отклонить извлечение устройств (включая каналы). Это вызывает
SpecialFileError. -
Для обычных файлов, включая жёсткие ссылки:
- Установить права чтения и записи владельца (
S_IWUSR). - Удалить права группы и других на выполнение (
S_IXOTH) если у владельца их нет (S_IXUSR).
- Установить права чтения и записи владельца (
- Для других файлов (каталоги), установить
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')
Интерфейс командной строки
Новая версия с 3.4.
Модуль tarfile предоставляет простой интерфейс командной строки для взаимодействия с архивами tar.
Если вы хотите создать новый архив tar, укажите его имя после опции -c, а затем перечислите имена файлов, которые должны быть включены:
$ python -m tarfile -c monty.tar spam.txt eggs.txt
Также можно передать каталог:
$ python -m tarfile -c monty.tar life-of-brian_1979/
Если вы хотите извлечь архив tar в текущий каталог, используйте опцию -e:
$ python -m tarfile -e monty.tar
Вы также можете извлечь архив tar в другой каталог, передав имя каталога:
$ python -m tarfile -e monty.tar other-dir/
Для отображения списка файлов в архиве tar используйте опцию -l:
$ python -m tarfile -l monty.tar
Параметры командной строки
-
-l <tarfile> -
--list <tarfile> -
Отобразить список файлов в архиве.
-
-c <tarfile> <source1> ... <sourceN> -
--create <tarfile> <source1> ... <sourceN> -
Создать архив tar из исходных файлов.
-
-e <tarfile> [<output_dir>] -
--extract <tarfile> [<output_dir>] -
Извлечь архив tar в текущий каталог, если output_dir не указан.
-
-t <tarfile> -
--test <tarfile> -
Проверить, является ли архив tar валидным.
-
-v, --verbose -
Подробный вывод.
-
--filter <filtername> -
Определяет фильтр для
--extract. См. Фильтры извлечения для получения подробностей. Принимаются только строковые имена (т.е.fully_trusted,tar, иdata).Новая версия с 3.10.12.
Примеры
Как извлечь весь архив 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)
Как прочитать сжатый 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:
- Формат ustar POSIX.1-1988 (
USTAR_FORMAT). Он поддерживает имена файлов длиной до 256 символов и имена ссылок до 100 символов. Максимальный размер файла составляет 8 ГиБ. Это старый и ограниченный, но широко поддерживаемый формат. - Формат GNU tar (
GNU_FORMAT). Он поддерживает длинные имена файлов и имен ссылок, файлы размером более 8 ГиБ и разреженные файлы. Это фактический стандарт на системах GNU/Linux.tarfileполностью поддерживает расширения GNU tar для длинных имен, поддержка разреженных файлов только для чтения. -
Формат pax POSIX.1-2001 (
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, но несовместим.
Проблемы с Unicode
Формат 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 или когда строки с замещающими символами сохраняются.
© 2001–2023 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.10/library/tarfile.html