shutil.rmtree在Windows上失败,“访问被拒绝”

在Python中,在包含只读文件的文件夹上运行shutil.rmtree时,会显示以下exception:

  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/但在Windows上? (不需要使用像unxutils或者cygwin这样的第三方工具,因为这个代码的目标是在安装了Python 2.6 w / PyWin32的裸机上运行)

检查这个问题:

Python脚本在Windows中运行的用户是什么?

显然,答案是将文件/文件夹更改为不可读取,然后将其删除。

这里是来自pathutils.py提到的pathutils.py的onerror()处理程序。

 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来删除它。

像这样(未经testing):

 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) 

那么,标记的解决scheme不适合我…这样做,而不是:

 os.system('rmdir /S /Q "{}"'.format(directory)) 

一个简单的解决方法是使用subprocess.call

 from subprocess import call call("rm -rf build/", shell=True) 

为了执行你想要的一切。

 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; path是导致它失败的那个函数的参数; 而exc_info是由sys.exc_info()返回的元组。 如果ignore_errors为false,onerror为None,则在此处引发exception