shutil.rmtree для удаления файлов только для чтения
Я хочу использовать shutil.rmtree
в Python, чтобы удалить каталог. Указанный каталог содержит .git
управляющий каталог, который помечает git как доступный только для чтения и скрытый.
Флаг только для чтения вызывает rmtree
терпеть неудачу. В Powershell я бы сделал "del -force" для принудительного удаления флага только для чтения. Есть ли эквивалент в Python? Я бы предпочел не ходить по всему дереву дважды, но onerror
Аргумент к rmtree, похоже, не повторяет операцию, поэтому я не могу использовать
def set_rw(operation, name, exc):
os.chmod(name, stat.S_IWRITE)
shutil.rmtree('path', onerror=set_rw)
4 ответа
После более подробного изучения, кажется, работает следующее:
def del_rw(action, name, exc):
os.chmod(name, stat.S_IWRITE)
os.remove(name)
shutil.rmtree(path, onerror=del_rw)
Другими словами, фактически удалите файл в функции onerror. (Возможно, вам придется проверить каталог в обработчике onerror и использовать rmdir в этом случае - мне это не нужно, но это может быть что-то конкретное в моей проблеме.
shutil.rmtree используется для удаления непустых каталогов (удаление дерева).
import os
import stat
import shutil
def del_ro_dir(dir_name):
'''Remove Read Only Directories'''
for (root, dirs, files) in os.walk(dir_name, topdown=True):
os.chmod(root,
# For user ...
stat.S_IRUSR |
stat.S_IWUSR |
stat.S_IXUSR |
# For group ...
stat.S_IWGRP |
stat.S_IRGRP |
stat.S_IXGRP |
# For other ...
stat.S_IROTH |
stat.S_IWOTH |
stat.S_IXOTH
)
shutil.rmtree(dir_name)
if __name__ == '__main__':
del_ro_dir('dir_name_here')
Чтобы удалить только файл, вы можете использовать следующий код:
import os
import stat
def rmv_rof(file_name):
'''Remov Read Only Files'''
if os.path.exists(file_name):
os.chmod(file_name, stat.S_IWRITE)
os.remove(file_name)
else:
print('The file does not exist.')
rmv_rof('file_name_here')
Вы можете прочитать подробную информацию здесь:
https://docs.python.org/3/library/os.html#os.chmod
https://docs.python.org/3/library/stat.html#module-stat
https://docs.python.org/3/library/shutil.html#rmtree-example
Вы могли бы просто пойти быстрым и грязным методом и сделать
subprocess.check_call(["rm", "-rf", filename])
. Скорее всего, не будет работать в Windows.
Вотrmtree
пример , скопированный прямо изshutil
документы (вероятно, добавленные после ОП):
import os, stat import shutil def remove_readonly(func, path, _): "Clear the readonly bit and reattempt the removal" os.chmod(path, stat.S_IWRITE) func(path) shutil.rmtree(directory, onexc=remove_readonly)
Обратите внимание, что есть небольшая разница в принятом ответе: в приведенном выше примере используетсяfunc
аргумент, а не явный вызовos.remove
.
Также обратите внимание, чтоonerror
устарел с версии Python 3.12 и будет заменен наonexc
.