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

时间:2010-04-16 21:57:56

标签: python windows file-permissions shutil

在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文件设置为只读。

所以问题是:解决这个问题的最简单的解决方法/修复是什么 - 考虑到我的目的是在Windows上做同等的rm -rf build/? (无需使用像unxutils或cygwin这样的第三方工具 - 因为此代码的目标是在安装了Python 2.6 w / PyWin32的裸Windows安装上运行)

5 个答案:

答案 0 :(得分:77)

检查这个问题:

What user do python scripts run as in windows?

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

@Sridhar Ratnakumar在评论中提到的来自pathutils.pyonerror()处理程序:

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

答案 1 :(得分:23)

我要说使用os.walk实现您自己的rmtree,以确保在尝试删除每个文件之前使用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)      

答案 2 :(得分:12)

好吧,标记的解决方案对我不起作用......而是这样做了:

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

答案 3 :(得分:0)

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,则忽略错误;否则,如果是恐怖的话  设置,调用它来处理带参数的错误(func,  path,exc_info)其中func是os.listdir,os.remove或os.rmdir;  path是导致它失败的那个函数的参数;和  exc_info是sys.exc_info()返回的元组。如果ignore_errors  是false,onerror是None,引发异常。输入代码

答案 4 :(得分:-1)

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

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

为了执行你想要的一切。

相关问题