shutil.md
1> **Источник:** https://python-all.ru/3.16/library/shutil.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# `shutil` – высокоуровневые операции с файлами89**Исходный код:** [Lib/shutil.py](https://python-all.ru/src/main/Lib/shutil.py)1011---1213Модуль `shutil` предоставляет ряд высокоуровневых операций с файлами и наборами файлов. В частности, предоставлены функции, которые поддерживают копирование и удаление файлов. Для операций с отдельными файлами см. также модуль [`os`](https://python-all.ru/3.16/library/os.html#module-os).1415> **Предупреждение**16>17> Даже функции копирования файлов высокого уровня ([`shutil.copy()`](https://python-all.ru/3.16/library/shutil.html#shutil.copy), [`shutil.copy2()`](https://python-all.ru/3.16/library/shutil.html#shutil.copy2)) не могут скопировать все метаданные файла.18>19> На платформах POSIX это означает, что владелец и группа файла теряются, а также ACL. На Mac OS не используются ресурсные форки и другие метаданные. Это означает, что ресурсы будут потеряны, а коды типа и создателя файла будут некорректными. В Windows владельцы файлов, ACL и альтернативные потоки данных не копируются.2021## Операции с каталогами и файлами2223#### `shutil.copyfileobj(fsrc, fdst[, length])`2425Копирует содержимое [объекта, подобного файлу](https://python-all.ru/3.16/glossary.html#term-file-object) *fsrc* в объект, подобный файлу, *fdst*. Целое число *length*, если задано, определяет размер буфера. В частности, отрицательное значение *length* означает копирование данных без разбиения исходных данных на куски; по умолчанию данные читаются порциями, чтобы избежать неконтролируемого потребления памяти. Обратите внимание, что если текущая позиция в файле объекта *fsrc* не равна 0, будет скопировано только содержимое от текущей позиции до конца файла.2627`copyfileobj()` *не* гарантирует, что поток назначения будет сброшен по завершении копирования. Если необходимо прочитать из назначения после завершения операции копирования (например, прочитать содержимое временного файла, скопированного из HTTP-потока), следует убедиться, что был вызван [`flush()`](https://python-all.ru/3.16/library/io.html#io.IOBase.flush) или [`close()`](https://python-all.ru/3.16/library/io.html#io.IOBase.close) для объекта, подобного файлу, перед попыткой чтения файла назначения.2829#### `shutil.copyfile(src, dst, *, follow_symlinks=True)`3031Копирует содержимое (без метаданных) файла с именем *src* в файл с именем *dst* и возвращает *dst* наиболее эффективным способом. *src* и *dst* – это [объекты, подобные путям](https://python-all.ru/3.16/glossary.html#term-path-like-object) или имена путей, заданные строками.3233*dst* должно быть полным именем целевого файла; см. [`copy()`](https://python-all.ru/3.16/library/shutil.html#shutil.copy) для копирования, принимающего путь к целевому каталогу. Если *src* и *dst* указывают на один и тот же файл, возбуждается [`SameFileError`](https://python-all.ru/3.16/library/shutil.html#shutil.SameFileError).3435Место назначения должно быть доступно для записи; в противном случае будет возбуждено исключение [`OSError`](https://python-all.ru/3.16/library/exceptions.html#OSError). Если *dst* уже существует, он будет заменён. Специальные файлы, такие как символьные или блочные устройства, каналы и сокеты, нельзя скопировать с помощью этой функции.3637Если *follow\_symlinks* имеет значение false и *src* является символической ссылкой, будет создана новая символическая ссылка вместо копирования файла, на который указывает *src*.3839Возбуждает [событие аудита](https://python-all.ru/3.16/library/sys.html#auditing) `shutil.copyfile` с аргументами `src`, `dst`.4041Изменено в версии 3.3: [`IOError`](https://python-all.ru/3.16/library/exceptions.html#IOError) ранее возбуждалось вместо [`OSError`](https://python-all.ru/3.16/library/exceptions.html#OSError). Добавлен аргумент *follow\_symlinks*. Теперь возвращает *dst*.4243Изменено в версии 3.4: Возбуждается [`SameFileError`](https://python-all.ru/3.16/library/shutil.html#shutil.SameFileError) вместо [`Error`](https://python-all.ru/3.16/library/shutil.html#shutil.Error). Поскольку первое является подклассом второго, это изменение обратно совместимо.4445Изменено в версии 3.8: Внутренне могут использоваться платформенно-зависимые системные вызовы быстрого копирования для более эффективного копирования файлов. См. раздел [Платформенно-зависимые эффективные операции копирования](https://python-all.ru/3.16/library/shutil.html#shutil-platform-dependent-efficient-copy-operations).4647Изменено в версии 3.15: [`SpecialFileError`](https://python-all.ru/3.16/library/shutil.html#shutil.SpecialFileError) теперь также возбуждается для сокетов и файлов устройств.4849#### `exception shutil.SpecialFileError`5051Это исключение возбуждается, когда [`copyfile()`](https://python-all.ru/3.16/library/shutil.html#shutil.copyfile) или [`copytree()`](https://python-all.ru/3.16/library/shutil.html#shutil.copytree) пытаются скопировать именованный канал, сокет или файл устройства.5253Добавлено в версии 2.7.5455#### `exception shutil.SameFileError`5657Это исключение возбуждается, если источник и назначение в [`copyfile()`](https://python-all.ru/3.16/library/shutil.html#shutil.copyfile) являются одним и тем же файлом.5859Добавлено в версии 3.4.6061#### `shutil.copymode(src, dst, *, follow_symlinks=True)`6263Копирует биты разрешений из *src* в *dst*. Содержимое файла, владелец и группа не изменяются. *src* и *dst* – это [объекты, подобные путям](https://python-all.ru/3.16/glossary.html#term-path-like-object) или имена путей, заданные строками. Если *follow\_symlinks* имеет значение false и оба *src* и *dst* являются символическими ссылками, `copymode()` попытается изменить режим самой *dst* (а не файла, на который она указывает). Эта функциональность доступна не на каждой платформе; обратитесь к [`copystat()`](https://python-all.ru/3.16/library/shutil.html#shutil.copystat) за дополнительной информацией. Если `copymode()` не может изменять символические ссылки на локальной платформе, и её просят это сделать, она ничего не делает и возвращает управление.6465Возбуждает [событие аудита](https://python-all.ru/3.16/library/sys.html#auditing) `shutil.copymode` с аргументами `src`, `dst`.6667Изменено в версии 3.3: Добавлен аргумент *follow\_symlinks*.6869#### `shutil.copystat(src, dst, *, follow_symlinks=True)`7071Копирует биты разрешений, время последнего доступа, время последнего изменения и флаги из *src* в *dst*. На Linux `copystat()` также копирует «расширенные атрибуты», где это возможно. Содержимое файла, владелец и группа не изменяются. *src* и *dst* – это [объекты, подобные путям](https://python-all.ru/3.16/glossary.html#term-path-like-object) или имена путей, заданные строками.7273Если *follow\_symlinks* имеет значение false и *src* и *dst* оба ссылаются на символические ссылки, `copystat()` будет работать с самими символическими ссылками, а не с файлами, на которые эти символические ссылки указывают – читая информацию из символической ссылки *src* и записывая информацию в символическую ссылку *dst*.7475> **Примечание**76>77> Не все платформы предоставляют возможность просматривать и изменять символические ссылки. Python сам может сообщить, какая функциональность доступна локально.78>79> - Если `os.chmod in os.supports_follow_symlinks` равен `True`, `copystat()` может изменять биты разрешений символической ссылки.80> - Если `os.utime in os.supports_follow_symlinks` равен `True`, `copystat()` может изменять время последнего доступа и изменения символической ссылки.81> - Если `os.chflags in os.supports_follow_symlinks` равно `True`, `copystat()` может изменять флаги символической ссылки. (`os.chflags` доступен не на всех платформах.)82>83> На платформах, где часть или вся эта функциональность недоступна, при попытке изменить символическую ссылку `copystat()` скопирует всё, что сможет. `copystat()` никогда не возвращает ошибку.84>85> Подробнее см. [`os.supports_follow_symlinks`](https://python-all.ru/3.16/library/os.html#os.supports_follow_symlinks).8687Возбуждает [событие аудита](https://python-all.ru/3.16/library/sys.html#auditing) `shutil.copystat` с аргументами `src`, `dst`.8889Изменено в версии 3.3: Добавлен аргумент *follow\_symlinks* и поддержка расширенных атрибутов Linux.9091#### `shutil.copy(src, dst, *, follow_symlinks=True)`9293Копирует файл *src* в файл или каталог *dst*. *src* и *dst* должны быть [path-like objects](https://python-all.ru/3.16/glossary.html#term-path-like-object) или строками. Если *dst* указывает на каталог, файл будет скопирован в *dst* с использованием базового имени из *src*. Если *dst* указывает на уже существующий файл, он будет заменён. Возвращает путь к созданному файлу.9495Если *follow\_symlinks* имеет значение false и *src* является символической ссылкой, *dst* будет создан как символическая ссылка. Если *follow\_symlinks* имеет значение true и *src* является символической ссылкой, *dst* будет копией файла, на который указывает *src*.9697`copy()` копирует данные файла и его режим доступа (см. [`os.chmod()`](https://python-all.ru/3.16/library/os.html#os.chmod)). Другие метаданные, такие как время создания и изменения файла, не сохраняются. Чтобы сохранить все метаданные исходного файла, используйте [`copy2()`](https://python-all.ru/3.16/library/shutil.html#shutil.copy2).9899Возбуждает [событие аудита](https://python-all.ru/3.16/library/sys.html#auditing) `shutil.copyfile` с аргументами `src`, `dst`.100101Возбуждает [событие аудита](https://python-all.ru/3.16/library/sys.html#auditing) `shutil.copymode` с аргументами `src`, `dst`.102103Изменено в версии 3.3: Добавлен аргумент *follow\_symlinks*. Теперь возвращает путь к созданному файлу.104105Изменено в версии 3.8: Внутренне могут использоваться платформенно-зависимые системные вызовы быстрого копирования для более эффективного копирования файлов. См. раздел [Платформенно-зависимые эффективные операции копирования](https://python-all.ru/3.16/library/shutil.html#shutil-platform-dependent-efficient-copy-operations).106107#### `shutil.copy2(src, dst, *, follow_symlinks=True)`108109Идентично [`copy()`](https://python-all.ru/3.16/library/shutil.html#shutil.copy), за исключением того, что `copy2()` также пытается сохранить метаданные файла.110111Когда *follow\_symlinks* имеет значение false и *src* является символической ссылкой, `copy2()` пытается скопировать все метаданные из символической ссылки *src* в новую символическую ссылку *dst*. Однако эта функциональность доступна не на всех платформах. На платформах, где часть или вся эта функциональность недоступна, `copy2()` сохранит все метаданные, которые сможет; `copy2()` никогда не вызывает исключение из-за невозможности сохранить метаданные файла.112113`copy2()` использует [`copystat()`](https://python-all.ru/3.16/library/shutil.html#shutil.copystat) для копирования метаданных файла. Подробнее о поддержке платформами изменения метаданных символических ссылок см. `copystat()`.114115Возбуждает [событие аудита](https://python-all.ru/3.16/library/sys.html#auditing) `shutil.copyfile` с аргументами `src`, `dst`.116117Возбуждает [событие аудита](https://python-all.ru/3.16/library/sys.html#auditing) `shutil.copystat` с аргументами `src`, `dst`.118119Изменено в версии 3.3: Добавлен аргумент *follow\_symlinks*, также предпринята попытка копировать расширенные атрибуты файловой системы (пока только Linux). Теперь возвращает путь к созданному файлу.120121Изменено в версии 3.8: Внутренне могут использоваться платформенно-зависимые системные вызовы быстрого копирования для более эффективного копирования файлов. См. раздел [Платформенно-зависимые эффективные операции копирования](https://python-all.ru/3.16/library/shutil.html#shutil-platform-dependent-efficient-copy-operations).122123#### `shutil.ignore_patterns(*patterns)`124125Эта фабричная функция создаёт функцию, которую можно использовать в качестве вызываемого объекта для аргумента *ignore* функции [`copytree()`](https://python-all.ru/3.16/library/shutil.html#shutil.copytree). Она игнорирует файлы и каталоги, соответствующие одному из переданных шаблонов *patterns* в стиле glob. См. пример ниже.126127#### `shutil.copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, ignore_dangling_symlinks=False, dirs_exist_ok=False)`128129Рекурсивно копирует всё дерево каталогов с корнем в *src* в каталог с именем *dst* и возвращает целевой каталог. Все промежуточные каталоги, необходимые для размещения *dst*, также будут созданы по умолчанию.130131Права доступа и временные метки каталогов копируются с помощью [`copystat()`](https://python-all.ru/3.16/library/shutil.html#shutil.copystat), отдельные файлы копируются с помощью [`copy2()`](https://python-all.ru/3.16/library/shutil.html#shutil.copy2).132133Если *symlinks* имеет значение true, символические ссылки в исходном дереве представляются как символические ссылки в новом дереве, и метаданные исходных ссылок будут скопированы насколько это позволяет платформа; если false или аргумент опущен, содержимое и метаданные файлов, на которые указывают ссылки, копируются в новое дерево.134135Когда *symlinks* имеет значение false, если файл, на который указывает символическая ссылка, не существует, в список ошибок, вызываемых исключением [`Error`](https://python-all.ru/3.16/library/shutil.html#shutil.Error), будет добавлено исключение в конце процесса копирования. Можно установить необязательный флаг *ignore\_dangling\_symlinks* в значение true, чтобы подавить это исключение. Обратите внимание, что этот параметр не действует на платформах, не поддерживающих [`os.symlink()`](https://python-all.ru/3.16/library/os.html#os.symlink).136137Если задан *ignore*, это должен быть вызываемый объект, который будет получать в качестве аргументов каталог, обрабатываемый `copytree()`, и список его содержимого, возвращённый [`os.listdir()`](https://python-all.ru/3.16/library/os.html#os.listdir). Поскольку `copytree()` вызывается рекурсивно, вызываемый объект *ignore* будет вызываться один раз для каждого копируемого каталога. Вызываемый объект должен возвращать последовательность имён каталогов и файлов относительно текущего каталога (т.е. подмножество элементов из его второго аргумента); эти имена будут игнорироваться в процессе копирования. [`ignore_patterns()`](https://python-all.ru/3.16/library/shutil.html#shutil.ignore_patterns) можно использовать для создания такого вызываемого объекта, который игнорирует имена на основе шаблонов в стиле glob.138139Если возникают исключения, вызывается [`Error`](https://python-all.ru/3.16/library/shutil.html#shutil.Error) со списком причин.140141Если задан *copy\_function*, это должен быть вызываемый объект, который будет использоваться для копирования каждого файла. Он будет вызван с исходным и целевым путями в качестве аргументов. По умолчанию используется [`copy2()`](https://python-all.ru/3.16/library/shutil.html#shutil.copy2), но можно использовать любую функцию с той же сигнатурой (например, [`copy()`](https://python-all.ru/3.16/library/shutil.html#shutil.copy)).142143Если *dirs\_exist\_ok* имеет значение false (по умолчанию) и *dst* уже существует, вызывается [`FileExistsError`](https://python-all.ru/3.16/library/exceptions.html#FileExistsError). Если *dirs\_exist\_ok* имеет значение true, операция копирования будет продолжена, если встретятся существующие каталоги, а файлы в дереве *dst* будут перезаписаны соответствующими файлами из дерева *src*.144145Возбуждает [событие аудита](https://python-all.ru/3.16/library/sys.html#auditing) `shutil.copytree` с аргументами `src`, `dst`.146147Изменено в версии 3.2: Добавлен аргумент *copy\_function* для возможности предоставления пользовательской функции копирования. Добавлен аргумент *ignore\_dangling\_symlinks* для подавления ошибок, связанных с висячими символическими ссылками, когда *symlinks* имеет значение false.148149Изменено в версии 3.3: Копирует метаданные, когда *symlinks* имеет значение false. Теперь возвращает *dst*.150151Изменено в версии 3.8: Внутренне могут использоваться платформенно-зависимые системные вызовы быстрого копирования для более эффективного копирования файлов. См. раздел [Платформенно-зависимые эффективные операции копирования](https://python-all.ru/3.16/library/shutil.html#shutil-platform-dependent-efficient-copy-operations).152153Изменено в версии 3.8: Добавлен параметр *dirs\_exist\_ok*.154155#### `shutil.rmtree(path, ignore_errors=False, onerror=None, *, onexc=None, dir_fd=None)`156157Удаляет всё дерево каталогов; *path* должен указывать на каталог (но не на символическую ссылку на каталог). Если *ignore\_errors* равно true, ошибки, возникающие при неудачном удалении, игнорируются; если false или не указано, такие ошибки обрабатываются вызовом обработчика, заданного параметром *onexc* или *onerror*, а если оба опущены, исключения передаются вызывающему коду.158159Эта функция может поддерживать [пути, относительные к дескрипторам каталогов](https://python-all.ru/3.16/library/os.html#dir-fd).160161> **Примечание**162>163> На платформах, поддерживающих необходимые функции на основе файловых дескрипторов, по умолчанию используется версия `rmtree()`, устойчивая к атакам через символические ссылки. На других платформах реализация `rmtree()` уязвима для такой атаки: при правильном выборе времени и обстоятельств злоумышленники могут манипулировать символическими ссылками в файловой системе, чтобы удалить файлы, к которым иначе у них не было бы доступа. Приложения могут использовать атрибут функции [`rmtree.avoids_symlink_attacks`](https://python-all.ru/3.16/library/shutil.html#shutil.rmtree.avoids_symlink_attacks), чтобы определить применимый вариант.164165Если *onexc* указан, он должен быть вызываемым объектом, принимающим три параметра: *function*, *path* и *excinfo*.166167Первый параметр, *function*, – это функция, вызвавшая исключение; он зависит от платформы и реализации. Второй параметр, *path*, – это имя пути, переданное функции *function*. Третий параметр, *excinfo*, – это исключение, которое было возбуждено. Исключения, возбуждённые в *onexc*, перехватываться не будут.168169Устаревший *onerror* аналогичен *onexc*, за исключением того, что третьим параметром он получает кортеж, возвращаемый из [`sys.exc_info()`](https://python-all.ru/3.16/library/sys.html#sys.exc_info).170171> **См. также**172>173> [пример rmtree](https://python-all.ru/3.16/library/shutil.html#shutil-rmtree-example) для обработки удаления дерева каталогов, содержащего файлы только для чтения.174175Возбуждает [событие аудита](https://python-all.ru/3.16/library/sys.html#auditing) `shutil.rmtree` с аргументами `path`, `dir_fd`.176177Изменено в версии 3.3: Добавлена версия, устойчивая к атакам через символические ссылки, которая используется автоматически, если платформа поддерживает функции на основе файловых дескрипторов.178179Изменено в версии 3.8: В Windows больше не удаляет содержимое точки соединения каталогов перед её удалением.180181Изменено в версии 3.11: Добавлен параметр *dir\_fd*.182183Изменено в версии 3.12: Добавлен параметр *onexc*, параметр *onerror* объявлен устаревшим.184185Изменено в версии 3.13: `rmtree()` теперь игнорирует исключения [`FileNotFoundError`](https://python-all.ru/3.16/library/exceptions.html#FileNotFoundError) для всех путей, кроме корневого. Исключения, отличные от [`OSError`](https://python-all.ru/3.16/library/exceptions.html#OSError) и подклассов `OSError`, теперь всегда передаются вызывающему коду.186187#### `rmtree.avoids_symlink_attacks`188189Указывает, предоставляют ли текущая платформа и реализация версию `rmtree()`, устойчивую к атакам через символические ссылки. В настоящее время это верно только для платформ, поддерживающих функции доступа к каталогам на основе файловых дескрипторов.190191Добавлено в версии 3.3.192193#### `shutil.move(src, dst, copy_function=copy2)`194195Рекурсивно перемещает файл или каталог (*src*) в другое место и возвращает целевой путь.196197Если *dst* – существующий каталог или символическая ссылка на каталог, то *src* перемещается внутрь этого каталога. Целевой путь внутри этого каталога не должен уже существовать.198199Если *dst* уже существует, но не является каталогом, он может быть перезаписан в зависимости от семантики [`os.rename()`](https://python-all.ru/3.16/library/os.html#os.rename).200201[`os.rename()`](https://python-all.ru/3.16/library/os.html#os.rename) предпочтительно используется внутри, когда *src* и целевой каталог находятся в одной файловой системе. Если `os.rename()` завершается неудачей из-за [`OSError`](https://python-all.ru/3.16/library/exceptions.html#OSError) (например, у пользователя есть разрешение на запись в целевой файл, но нет разрешения на запись в его родительский каталог), этот метод переключается на использование *copy\_function*; в этом случае *src* копируется в целевой путь с помощью *copy\_function*, а затем удаляется.202203В случае символических ссылок новая символическая ссылка, указывающая на цель *src*, будет создана в месте назначения (или как само место назначения), а *src* будет удалён.204205Если указан *copy\_function*, он должен быть вызываемым объектом, принимающим два аргумента: *src* и целевой путь. Он будет использоваться для копирования *src* в целевой путь, если [`os.rename()`](https://python-all.ru/3.16/library/os.html#os.rename) не может быть использован. Если исходный объект – каталог, вызывается [`copytree()`](https://python-all.ru/3.16/library/shutil.html#shutil.copytree), которому передаётся *copy\_function*. Значение *copy\_function* по умолчанию – [`copy2()`](https://python-all.ru/3.16/library/shutil.html#shutil.copy2). Использование [`copy()`](https://python-all.ru/3.16/library/shutil.html#shutil.copy) в качестве *copy\_function* позволяет выполнить перемещение, когда невозможно скопировать метаданные, ценой отсутствия копирования метаданных.206207Возбуждает [событие аудита](https://python-all.ru/3.16/library/sys.html#auditing) `shutil.move` с аргументами `src`, `dst`.208209Изменено в версии 3.3: Добавлена явная обработка символических ссылок для внешних файловых систем, что адаптирует поведение к GNU **mv**. Теперь возвращает *dst*.210211Изменено в версии 3.5: Добавлен именованный аргумент *copy\_function*.212213Изменено в версии 3.8: Внутренне могут использоваться платформенно-зависимые системные вызовы быстрого копирования для более эффективного копирования файлов. См. раздел [Платформенно-зависимые эффективные операции копирования](https://python-all.ru/3.16/library/shutil.html#shutil-platform-dependent-efficient-copy-operations).214215Изменено в версии 3.9: Принимает [объект, подобный пути](https://python-all.ru/3.16/glossary.html#term-path-like-object) как для *src*, так и для *dst*.216217#### `shutil.disk_usage(path)`218219Возвращает статистику использования диска для указанного пути в виде [именованного кортежа](https://python-all.ru/3.16/glossary.html#term-named-tuple) с атрибутами *total*, *used* и *free*, которые представляют общий, используемый и свободный объём в байтах. *path* может быть файлом или каталогом.220221> **Примечание**222>223> В файловых системах Unix *path* должен указывать на путь внутри **смонтированного** раздела файловой системы. На этих платформах CPython не пытается получить информацию об использовании диска из не смонтированных файловых систем.224225Добавлено в версии 3.3.226227Изменено в версии 3.8: В Windows *path* теперь может быть файлом или каталогом.228229[Доступность](https://python-all.ru/3.16/library/intro.html#availability): Unix, Windows.230231#### `shutil.chown(path, user=None, group=None, *, dir_fd=None, follow_symlinks=True)`232233Изменяет владельца *user* и/или группу *group* для указанного *path*.234235*user* может быть системным именем пользователя или uid; то же самое относится к *group*. Требуется хотя бы один аргумент.236237См. также [`os.chown()`](https://python-all.ru/3.16/library/os.html#os.chown) – базовую функцию.238239Вызывает [событие аудита](https://python-all.ru/3.16/library/sys.html#auditing) `shutil.chown` с аргументами `path`, `user`, `group`.240241[Доступность](https://python-all.ru/3.16/library/intro.html#availability): Unix.242243Добавлено в версии 3.3.244245Изменено в версии 3.13: Добавлены параметры *dir\_fd* и *follow\_symlinks*.246247#### `shutil.which(cmd, mode=os.F_OK | os.X_OK, path=None)`248249Возвращает путь к исполняемому файлу, который был бы запущен, если бы была вызвана заданная команда *cmd*. Если команда *cmd* не будет вызвана, возвращает `None`.250251*mode* – это маска прав доступа, передаваемая в [`os.access()`](https://python-all.ru/3.16/library/os.html#os.access), по умолчанию определяющая, существует ли файл и является ли он исполняемым.252253*path* – это `PATH` строка, задающая каталоги для поиска, разделённые [`os.pathsep`](https://python-all.ru/3.16/library/os.html#os.pathsep). Если *path* не указан, считывается переменная окружения `PATH` из [`os.environ`](https://python-all.ru/3.16/library/os.html#os.environ), с переходом на [`os.defpath`](https://python-all.ru/3.16/library/os.html#os.defpath), если она не задана.254255Если *cmd* содержит компонент каталога, `which()` проверяет только указанный путь напрямую и не ищет в каталогах, перечисленных в *path* или в переменной окружения `PATH` системы.256257В Windows текущий каталог добавляется в начало *path*, если *mode* не включает `os.X_OK`. Если *mode* включает `os.X_OK`, то будет вызван Windows API `NeedCurrentDirectoryForExePathW`, чтобы определить, следует ли добавлять текущий каталог в начало *path*. Чтобы избежать обращения к текущему рабочему каталогу для исполняемых файлов: установите переменную окружения `NoDefaultCurrentDirectoryInExePath`.258259Также в Windows переменная окружения `PATHEXT` используется для разрешения команд, которые могут ещё не содержать расширение. Например, если вызвать `shutil.which("python")`, `which()` будет искать `PATHEXT`, чтобы узнать, что нужно искать `python.exe` в каталогах *path*. Например, в Windows:260261```python262>>> shutil.which("python")263'C:\\Python33\\python.EXE'264```265266Это также применяется, когда *cmd* – это путь, содержащий компонент каталога:267268```python269>>> shutil.which("C:\\Python33\\python")270'C:\\Python33\\python.EXE'271```272273Добавлено в версии 3.3.274275Изменено в версии 3.8: Теперь принимается тип [`bytes`](https://python-all.ru/3.16/library/stdtypes.html#bytes). Если тип *cmd* – `bytes`, то тип результата также `bytes`.276277Изменено в версии 3.12: В Windows текущий каталог больше не добавляется в начало пути поиска, если *mode* включает `os.X_OK` и WinAPI `NeedCurrentDirectoryForExePathW(cmd)` равен false, в противном случае текущий каталог добавляется в начало, даже если он уже есть в пути поиска; `PATHEXT` теперь используется даже когда *cmd* содержит компонент каталога или заканчивается расширением, которое есть в `PATHEXT`; и теперь можно найти имена файлов, не имеющие расширения.278279#### `exception shutil.Error`280281Подкласс [`OSError`](https://python-all.ru/3.16/library/exceptions.html#OSError), собирающий исключения, возникшие при операции с несколькими файлами. Для [`copytree()`](https://python-all.ru/3.16/library/shutil.html#shutil.copytree) аргумент исключения – это список из 3-кортежей (*srcname*, *dstname*, *исключение*).282283### Эффективные операции копирования, зависящие от платформы284285Начиная с Python 3.8 все функции, связанные с копированием файлов ([`copyfile()`](https://python-all.ru/3.16/library/shutil.html#shutil.copyfile), [`copy()`](https://python-all.ru/3.16/library/shutil.html#shutil.copy), [`copy2()`](https://python-all.ru/3.16/library/shutil.html#shutil.copy2), [`copytree()`](https://python-all.ru/3.16/library/shutil.html#shutil.copytree) и [`move()`](https://python-all.ru/3.16/library/shutil.html#shutil.move)), могут использовать платформенно-зависимые системные вызовы «быстрого копирования» для более эффективного копирования файла (см. [bpo-33671](https://python-all.ru/3.16/library/shutil.html)). «Быстрое копирование» означает, что операция копирования происходит внутри ядра, минуя использование буферов пользовательского пространства в Python, как в «`outfd.write(infd.read())`».286287В macOS [fcopyfile](https://python-all.ru/3.16/library/shutil.html) используется для копирования содержимого файла (не метаданных).288289В Linux используется [`os.copy_file_range()`](https://python-all.ru/3.16/library/os.html#os.copy_file_range) или [`os.sendfile()`](https://python-all.ru/3.16/library/os.html#os.sendfile).290291В Solaris используется [`os.sendfile()`](https://python-all.ru/3.16/library/os.html#os.sendfile).292293В Windows [`shutil.copyfile()`](https://python-all.ru/3.16/library/shutil.html#shutil.copyfile) использует больший размер буфера по умолчанию (1 МиБ вместо 64 КиБ) и [`memoryview()`](https://python-all.ru/3.16/library/stdtypes.html#memoryview)-основанный вариант [`shutil.copyfileobj()`](https://python-all.ru/3.16/library/shutil.html#shutil.copyfileobj), который всё ещё читает и записывает в цикле. [`shutil.copy2()`](https://python-all.ru/3.16/library/shutil.html#shutil.copy2) использует нативный вызов `CopyFile2` в Windows, что является наиболее эффективным методом, поддерживает копирование при записи и сохраняет метаданные.294295Если операция быстрого копирования завершается ошибкой и в целевой файл не было записано никаких данных, то shutil незаметно переключится внутренне на менее эффективную функцию [`copyfileobj()`](https://python-all.ru/3.16/library/shutil.html#shutil.copyfileobj).296297Изменено в версии 3.8.298299Изменено в версии 3.14: Solaris теперь использует [`os.sendfile()`](https://python-all.ru/3.16/library/os.html#os.sendfile).300301Изменено в версии 3.14: Копирование при записи или копирование на стороне сервера может использоваться внутренне через [`os.copy_file_range()`](https://python-all.ru/3.16/library/os.html#os.copy_file_range) в поддерживаемых файловых системах Linux.302303### Пример copytree304305Пример, использующий вспомогательную функцию [`ignore_patterns()`](https://python-all.ru/3.16/library/shutil.html#shutil.ignore_patterns):306307```python308from shutil import copytree, ignore_patterns309310copytree(source, destination, ignore=ignore_patterns('*.pyc', 'tmp*'))311```312313При этом будет скопировано всё, кроме файлов `.pyc` и файлов или каталогов, имена которых начинаются с `tmp`.314315Ещё один пример, использующий аргумент *ignore* для добавления вызова журналирования:316317```python318from shutil import copytree319import logging320321def _logpath(path, names):322 logging.info('Working in %s', path)323 return [] # ничего не будет проигнорировано324325copytree(source, destination, ignore=_logpath)326```327328### Пример rmtree329330В этом примере показано, как удалить дерево каталогов в Windows, где у некоторых файлов установлен бит только для чтения. Используется колбэк onexc, чтобы снять бит только для чтения и повторить удаление. Любой последующий сбой будет распространён.331332```python333import os, stat334import shutil335336def remove_readonly(func, path, _):337 "Clear the readonly bit and reattempt the removal"338 os.chmod(path, stat.S_IWRITE)339 func(path)340341shutil.rmtree(directory, onexc=remove_readonly)342```343344## Операции архивирования345346Добавлено в версии 3.2.347348Изменено в версии 3.5: Добавлена поддержка формата *xztar*.349350Также предоставляются высокоуровневые утилиты для создания и чтения сжатых и архивных файлов. Они основаны на модулях [`zipfile`](https://python-all.ru/3.16/library/zipfile.html#module-zipfile) и [`tarfile`](https://python-all.ru/3.16/library/tarfile.html#module-tarfile).351352#### `shutil.make_archive(base_name, format[, root_dir[, base_dir[, verbose[, dry_run[, owner[, group[, logger]]]]]]])`353354Создаёт архивный файл (например, zip или tar) и возвращает его имя.355356*base\_name* – строка или [объект, подобный пути](https://python-all.ru/3.16/glossary.html#term-path-like-object), указывающая имя создаваемого файла, включая путь, без расширения, характерного для формата.357358*format* – формат архива: один из «zip» (если доступен модуль [`zlib`](https://python-all.ru/3.16/library/zlib.html#module-zlib)), «tar», «gztar» (если доступен модуль `zlib`), «bztar» (если доступен модуль [`bz2`](https://python-all.ru/3.16/library/bz2.html#module-bz2)), «xztar» (если доступен модуль [`lzma`](https://python-all.ru/3.16/library/lzma.html#module-lzma)) или «zstdtar» (если доступен модуль [`compression.zstd`](https://python-all.ru/3.16/library/compression.zstd.html#module-compression.zstd)).359360*root\_dir* – строка или [объект, подобный пути](https://python-all.ru/3.16/glossary.html#term-path-like-object), указывающая каталог, который будет корневым каталогом архива; все пути в архиве будут относительно него; например, мы обычно переходим в *root\_dir* перед созданием архива.361362*base\_dir* – строка или [объект, подобный пути](https://python-all.ru/3.16/glossary.html#term-path-like-object), указывающая каталог, откуда начинается архивирование; то есть *base\_dir* будет общим префиксом для всех файлов и каталогов в архиве. *base\_dir* должен задаваться относительно *root\_dir*. См. [Пример архивирования с base\_dir](https://python-all.ru/3.16/library/shutil.html#shutil-archiving-example-with-basedir) о том, как использовать *base\_dir* и *root\_dir* вместе.363364*root\_dir* и *base\_dir* по умолчанию равны текущему каталогу.365366Если *dry\_run* равен true, архив не создаётся, но операции, которые были бы выполнены, записываются в журнал *logger*.367368*owner* и *group* используются при создании tar-архива. По умолчанию используются текущий владелец и группа.369370*logger* должен быть объектом, совместимым с [**PEP 282**](https://python-all.ru/3.16/library/shutil.html), обычно экземпляром [`logging.Logger`](https://python-all.ru/3.16/library/logging.html#logging.Logger).371372Аргумент *verbose* не используется и является устаревшим.373374Возбуждает [событие аудита](https://python-all.ru/3.16/library/sys.html#auditing) `shutil.make_archive` с аргументами `base_name`, `format`, `root_dir`, `base_dir`.375376> **Примечание**377>378> Эта функция не является потокобезопасной, если пользовательские архиваторы, зарегистрированные с помощью [`register_archive_format()`](https://python-all.ru/3.16/library/shutil.html#shutil.register_archive_format), не поддерживают аргумент *root\_dir*. В этом случае она временно изменяет текущий рабочий каталог процесса на *root\_dir* для выполнения архивации.379380Изменено в версии 3.8: Теперь используется современный формат pax (POSIX.1-2001) вместо устаревшего формата GNU для архивов, созданных с помощью `format="tar"`.381382Изменено в версии 3.10.6: Эта функция теперь потокобезопасна при создании стандартных `.zip` и tar-архивов.383384Изменено в версии 3.15: Принимает [объект, подобный пути](https://python-all.ru/3.16/glossary.html#term-path-like-object) для *base\_name*, *root\_dir* и *base\_dir*.385386#### `shutil.get_archive_formats()`387388Возвращает список поддерживаемых форматов архивации. Каждый элемент возвращаемой последовательности – это кортеж `(name, description)`.389390По умолчанию `shutil` предоставляет следующие форматы:391392- *zip*: ZIP-файл (если доступен модуль [`zlib`](https://python-all.ru/3.16/library/zlib.html#module-zlib)).393- *tar*: Несжатый tar-файл. Использует формат pax (POSIX.1-2001) для новых архивов.394- *gztar*: tar-файл, сжатый gzip (если доступен модуль [`zlib`](https://python-all.ru/3.16/library/zlib.html#module-zlib)).395- *bztar*: tar-файл, сжатый bzip2 (если доступен модуль [`bz2`](https://python-all.ru/3.16/library/bz2.html#module-bz2)).396- *xztar*: tar-файл, сжатый xz (если доступен модуль [`lzma`](https://python-all.ru/3.16/library/lzma.html#module-lzma)).397- *zstdtar*: tar-файл, сжатый Zstandard (если доступен модуль [`compression.zstd`](https://python-all.ru/3.16/library/compression.zstd.html#module-compression.zstd)).398399Можно зарегистрировать новые форматы или предоставить собственный архиватор для любого существующего формата, используя [`register_archive_format()`](https://python-all.ru/3.16/library/shutil.html#shutil.register_archive_format).400401#### `shutil.register_archive_format(name, function[, extra_args[, description]])`402403Регистрирует архиватор для формата *name*.404405*function* – это вызываемый объект, который будет использоваться для создания архивов. Вызываемый объект получает *base\_name* создаваемого файла, затем *base\_dir* (по умолчанию [`os.curdir`](https://python-all.ru/3.16/library/os.html#os.curdir)), откуда начинать архивацию. Дополнительные аргументы передаются как именованные: *owner*, *group*, *dry\_run* и *logger* (как передано в [`make_archive()`](https://python-all.ru/3.16/library/shutil.html#shutil.make_archive)).406407Если у *function* есть пользовательский атрибут `function.supports_root_dir`, установленный в `True`, то аргумент *root\_dir* передаётся как именованный. В противном случае текущий рабочий каталог процесса временно изменяется на *root\_dir* перед вызовом *function*. В этом случае [`make_archive()`](https://python-all.ru/3.16/library/shutil.html#shutil.make_archive) не является потокобезопасным.408409Если указан, *extra\_args* – это последовательность пар `(name, value)`, которые будут использоваться как дополнительные именованные аргументы при вызове архиватора.410411*description* используется [`get_archive_formats()`](https://python-all.ru/3.16/library/shutil.html#shutil.get_archive_formats), который возвращает список архиваторов. По умолчанию – пустая строка.412413Изменено в версии 3.12: Добавлена поддержка функций, поддерживающих аргумент *root\_dir*.414415#### `shutil.unregister_archive_format(name)`416417Удалите имя формата архива *name* из списка поддерживаемых форматов.418419#### `shutil.unpack_archive(filename[, extract_dir[, format[, filter]]])`420421Распаковывает архив. *filename* – это полный путь к архиву.422423*extract\_dir* – имя целевой директории, в которую распаковывается архив. Если не указано, используется текущая рабочая директория.424425*format* – формат архива: одно из значений «zip», «tar», «gztar», «bztar», «xztar» или «zstdtar». Или любой другой формат, зарегистрированный с помощью [`register_unpack_format()`](https://python-all.ru/3.16/library/shutil.html#shutil.register_unpack_format). Если не указан, `unpack_archive()` использует расширение имени файла архива и проверяет, зарегистрирован ли распаковщик для этого расширения. Если таковой не найден, возбуждается [`ValueError`](https://python-all.ru/3.16/library/exceptions.html#ValueError).426427Ключевой аргумент *filter* передаётся в нижележащую функцию распаковки. Для zip-файлов *filter* не принимается. Для tar-файлов рекомендуется использовать `'data'` (по умолчанию начиная с Python 3.14), если только не используются возможности, специфичные для tar и UNIX-подобных файловых систем. (Подробнее см. [Фильтры извлечения](https://python-all.ru/3.16/library/tarfile.html#tarfile-extraction-filter)).428429Вызывает [событие аудита](https://python-all.ru/3.16/library/sys.html#auditing) `shutil.unpack_archive` с аргументами `filename`, `extract_dir`, `format`.430431> **Предупреждение**432>433> Никогда не извлекайте архивы из ненадёжных источников без предварительной проверки. Возможно создание файлов за пределами пути, указанного в аргументе *extract\_dir*, например, членов архива с абсолютными именами файлов или именами, содержащими «..».434>435> Начиная с Python 3.14, значения по умолчанию для обоих встроенных форматов (zip и tar) предотвращают наиболее опасные из таких проблем безопасности, но не предотвращают *все* нежелательные действия. Прочитайте раздел [Подсказки для дальнейшей проверки](https://python-all.ru/3.16/library/tarfile.html#tarfile-further-verification) для получения подробностей, касающихся tar.436437Изменено в версии 3.7: Принимает [объект, подобный пути](https://python-all.ru/3.16/glossary.html#term-path-like-object) для *filename* и *extract\_dir*.438439Изменено в версии 3.12: Добавлен аргумент *filter*.440441#### `shutil.register_unpack_format(name, extensions, function[, extra_args[, description]])`442443Регистрирует формат распаковки. *name* – имя формата, а *extensions* – список расширений, соответствующих этому формату, например `.zip` для Zip-файлов.444445*function* – вызываемый объект, который будет использоваться для распаковки архивов. Вызываемый объект получит:446447- путь к архиву в качестве позиционного аргумента;448- каталог, в который необходимо извлечь архив, в качестве позиционного аргумента;449- возможно, ключевой аргумент *filter*, если он был передан в [`unpack_archive()`](https://python-all.ru/3.16/library/shutil.html#shutil.unpack_archive);450- дополнительные ключевые аргументы, заданные *extra\_args* в виде последовательности кортежей `(name, value)`.451452*description* может быть указано для описания формата и будет возвращено функцией [`get_unpack_formats()`](https://python-all.ru/3.16/library/shutil.html#shutil.get_unpack_formats).453454#### `shutil.unregister_unpack_format(name)`455456Отменяет регистрацию формата распаковки. *name* – имя формата.457458#### `shutil.get_unpack_formats()`459460Возвращает список всех зарегистрированных форматов для распаковки. Каждый элемент возвращаемой последовательности является кортежем `(name, extensions, description)`.461462По умолчанию `shutil` предоставляет следующие форматы:463464- *zip*: ZIP-файл (распаковка сжатых файлов работает, только если доступен соответствующий модуль).465- *tar*: несжатый tar-файл.466- *gztar*: tar-файл, сжатый gzip (если доступен модуль [`zlib`](https://python-all.ru/3.16/library/zlib.html#module-zlib)).467- *bztar*: tar-файл, сжатый bzip2 (если доступен модуль [`bz2`](https://python-all.ru/3.16/library/bz2.html#module-bz2)).468- *xztar*: tar-файл, сжатый xz (если доступен модуль [`lzma`](https://python-all.ru/3.16/library/lzma.html#module-lzma)).469- *zstdtar*: tar-файл, сжатый Zstandard (если доступен модуль [`compression.zstd`](https://python-all.ru/3.16/library/compression.zstd.html#module-compression.zstd)).470471Вы можете зарегистрировать новые форматы или предоставить собственный распаковщик для любых существующих форматов, используя [`register_unpack_format()`](https://python-all.ru/3.16/library/shutil.html#shutil.register_unpack_format).472473### Пример архивации474475В этом примере мы создаём tar-архив, сжатый gzip, содержащий все файлы, найденные в каталоге `.ssh` пользователя:476477```python478>>> from shutil import make_archive479>>> import os480>>> archive_name = os.path.expanduser(os.path.join('~', 'myarchive'))481>>> root_dir = os.path.expanduser(os.path.join('~', '.ssh'))482>>> make_archive(archive_name, 'gztar', root_dir)483'/Users/tarek/myarchive.tar.gz'484```485486Полученный архив содержит:487488```console489$ tar -tzvf /Users/tarek/myarchive.tar.gz490drwx------ tarek/staff 0 2010-02-01 16:23:40 ./491-rw-r--r-- tarek/staff 609 2008-06-09 13:26:54 ./authorized_keys492-rwxr-xr-x tarek/staff 65 2008-06-09 13:26:54 ./config493-rwx------ tarek/staff 668 2008-06-09 13:26:54 ./id_dsa494-rwxr-xr-x tarek/staff 609 2008-06-09 13:26:54 ./id_dsa.pub495-rw------- tarek/staff 1675 2008-06-09 13:26:54 ./id_rsa496-rw-r--r-- tarek/staff 397 2008-06-09 13:26:54 ./id_rsa.pub497-rw-r--r-- tarek/staff 37192 2010-02-06 18:23:10 ./known_hosts498```499500### Пример архивации с *base\_dir*501502В этом примере, аналогичном [предыдущему](https://python-all.ru/3.16/library/shutil.html#shutil-archiving-example), показано, как использовать [`make_archive()`](https://python-all.ru/3.16/library/shutil.html#shutil.make_archive), но на этот раз с применением *base\_dir*. Теперь структура каталогов выглядит так:503504```console505$ tree tmp506tmp507└── root508 └── structure509 ├── content510 └── please_add.txt511 └── do_not_add.txt512```513514В итоговый архив должен быть включён `please_add.txt`, а `do_not_add.txt` – нет. Поэтому используется следующее:515516```python517>>> from shutil import make_archive518>>> import os519>>> archive_name = os.path.expanduser(os.path.join('~', 'myarchive'))520>>> make_archive(521... archive_name,522... 'tar',523... root_dir='tmp/root',524... base_dir='structure/content',525... )526'/Users/tarek/myarchive.tar'527```528529Вывод списка файлов в полученном архиве даёт:530531```console532$ python -m tarfile -l /Users/tarek/myarchive.tar533structure/content/534structure/content/please_add.txt535```536537## Запрос размера выходного терминала538539#### `shutil.get_terminal_size(fallback=(columns, lines))`540541Получить размер окна терминала.542543Для каждого из двух измерений проверяется переменная окружения, соответственно `COLUMNS` и `LINES`. Если переменная определена и её значение – положительное целое число, оно используется.544545Если `COLUMNS` или `LINES` не определена (что бывает чаще всего), терминал, подключённый к [`sys.__stdout__`](https://python-all.ru/3.16/library/sys.html#sys.__stdout__), опрашивается с помощью вызова [`os.get_terminal_size()`](https://python-all.ru/3.16/library/os.html#os.get_terminal_size).546547Если размер терминала не удаётся опросить – либо из-за того, что система не поддерживает опрос, либо потому, что нет подключения к терминалу, – используется значение, указанное в параметре `fallback`. `fallback` по умолчанию равно `(80, 24)`, это размер, используемый по умолчанию многими эмуляторами терминала.548549Возвращаемое значение – именованный кортеж типа [`os.terminal_size`](https://python-all.ru/3.16/library/os.html#os.terminal_size).550551См. также: The Single UNIX Specification, Version 2, [Другие переменные окружения](https://python-all.ru/3.16/library/shutil.html).552553Добавлено в версии 3.3.554555Изменено в версии 3.11: Значения `fallback` также используются, если [`os.get_terminal_size()`](https://python-all.ru/3.16/library/os.html#os.get_terminal_size) возвращает нули.556