shutil.rmtree fails on Windows with 'Access is denied'
在python中,在包含只读文件的文件夹上运行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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' |
在文件属性对话框中,我注意到
所以问题是:如果我的目的是在Windows上做一个与
检查这个问题:
在Windows中,python脚本的运行方式是什么?
显然,答案是将文件/文件夹更改为非只读,然后将其删除。
以下是@sridhar ratnakumar在评论中提到的来自EDOCX1[1]的EDOCX1[0]处理程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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 |
我想说,使用os.walk实现您自己的rmtree,在尝试删除每个文件之前使用os.chmod确保访问。
类似这样的事情(未测试):
1 2 3 4 5 6 7 8 9 10 11 12 | 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) |
嗯,标记的解决方案对我不起作用…而是这样做了:
1 | os.system('rmdir /S /Q"{}"'.format(directory)) |
1 2 3 4 5 6 7 8 9 10 | 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 |
如果设置了"忽略错误",则忽略错误;否则,如果设置了"忽略错误"如果设置了,则调用它以使用参数(func,路径,exc_info),其中func是os.listdir、os.remove或os.rmdir;path是导致它失败的函数的参数;并且exc-info是sys.exc-info()返回的元组。如果忽略错误为false,onerror为none,引发异常。请在此处输入代码
一个简单的解决方法是使用
1 2 | from subprocess import call call("rm -rf build/", shell=True) |
为了执行你想要的一切。