PULTIL.RMTREE не удается в Windows с «доступом запрещено» [дубликат
-
27-09-2019 - |
Вопрос
Этот вопрос уже имеет ответ здесь:
- Удаление каталога в Python 6 ответов
В Python, при запуске shutil.rmtree
Над папкой, которая содержит файл только для чтения, напечатано следующее исключение:
File "C:\Python26\lib\shutil.py", line 216, in rmtree
rmtree(fullname, ignore_errors, onerror)
File "C:\Python26\lib\shutil.py", line 216, in rmtree
rmtree(fullname, ignore_errors, onerror)
File "C:\Python26\lib\shutil.py", line 216, in rmtree
rmtree(fullname, ignore_errors, onerror)
File "C:\Python26\lib\shutil.py", line 216, in rmtree
rmtree(fullname, ignore_errors, onerror)
File "C:\Python26\lib\shutil.py", line 216, in rmtree
rmtree(fullname, ignore_errors, onerror)
File "C:\Python26\lib\shutil.py", line 216, in rmtree
rmtree(fullname, ignore_errors, onerror)
File "C:\Python26\lib\shutil.py", line 216, in rmtree
rmtree(fullname, ignore_errors, onerror)
File "C:\Python26\lib\shutil.py", line 221, in rmtree
onerror(os.remove, fullname, sys.exc_info())
File "C:\Python26\lib\shutil.py", line 219, in rmtree
os.remove(fullname)
WindowsError: [Error 5] Access is denied: 'build\\tcl\\tcl8.5\\msgs\\af.msg'
Глядя в диалог свойств файла, я заметил, что af.msg
Файл устанавливается только для чтения.
Так что вопрос в том, что простейший обходной путь / решение, чтобы обойти эту проблему - учитывая, что мое намерение состоит в том, чтобы сделать эквивалент rm -rf build/
Но на окнах? (Без необходимости использовать сторонние инструменты, такие как Unxutils или Cygwin - поскольку этот код предназначен для запуска на голых окнах, установленных с Python 2.6 W / Pywin32)
Решение
Проверьте этот вопрос:
Какой пользователь делает сценарии Python, как в Windows?
Видимо, ответ - это изменить файл / папку, чтобы не быть только для чтения, а затем удалить его.
Вот onerror()
обработчик от pathutils.py
упоминается @sridhar Ratnakumar в комментариях:
def onerror(func, path, exc_info):
"""
Error handler for ``shutil.rmtree``.
If the error is due to an access error (read only file)
it attempts to add write permission and then retries.
If the error is for another reason it re-raises the error.
Usage : ``shutil.rmtree(path, onerror=onerror)``
"""
import stat
if not os.access(path, os.W_OK):
# Is the error an access error ?
os.chmod(path, stat.S_IWUSR)
func(path)
else:
raise
Другие советы
Я бы сказал, реализовать свой собственный rmtree с os.walk. что обеспечивает доступ с использованием os.chmod. на каждом файле, прежде чем пытаться удалить его.
Что-то вроде этого (непроверенная):
import os
import stat
def rmtree(top):
for root, dirs, files in os.walk(top, topdown=False):
for name in files:
filename = os.path.join(root, name)
os.chmod(filename, stat.S_IWUSR)
os.remove(filename)
for name in dirs:
os.rmdir(os.path.join(root, name))
os.rmdir(top)
Ну, отмеченное решение не работало для меня ... сделал это вместо этого:
os.system('rmdir /S /Q "{}"'.format(directory))
shutil.rmtree(path,ignore_errors=False,onerror=errorRemoveReadonly)
def errorRemoveReadonly(func, path, exc):
excvalue = exc[1]
if func in (os.rmdir, os.remove) and excvalue.errno == errno.EACCES:
# change the file to be readable,writable,executable: 0777
os.chmod(path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
# retry
func(path)
else:
raiseenter code here
Если Ignore_Errors установлен, ошибки игнорируются; В противном случае, если OnError установлен, он вызывается для обработки ошибки с аргументами (Func, Path, Exc_info), где Func является OS.Listdir, OS.Remove или OS.RMDIR; путь - это аргумент для этой функции, которая заставила его потерпеть неудачу; и exc_info - кортеж, возвращенный sys.exc_info (). Если ignore_Errors ложный, и OneRror - нет, исключение поднимается.
Простой обходной путь использует subprocess.call
from subprocess import call
call("rm -rf build/", shell=True)
Для того, чтобы выполнить все, что вы хотите.