python shutil.rmtree_关于python:shutil.rmtree在Windows上失败并且“访问被拒绝”

在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上运行)

shutil.rmtree使用os.remove删除文件。os.remove删除只读文件很好(至少在UNIX上)。如果文件正在使用中,os.remove无法删除Windows上的文件。

在python中删除目录可能重复

相关:如何避免"Windows错误:&91;错误5&93;访问被拒绝"

检查这个问题:

在Windows中,python脚本的运行方式是什么?

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

以下是@sridhar ratnakumar在评论中提到的来自EDOCX1[1]的EDOCX1[0]处理程序:

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, οnerrοr=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

呵呵。我刚刚在voidspace.org.uk/downloads/pathutils.py上发现了onerror处理程序。

…发现通过trac.pythonpaste.org/pythonpaste/ticket/359

尽管此答案的注释状态为"将文件/文件夹更改为非只读",但我仍然收到对只读文件夹的访问被拒绝。不过,这个实现是有效的。

向那些按原样粘贴此函数的副本发出警告,将import stat移出该函数。我在接收RuntimeError: sys.meta_path must be a list of import hooks的时候,把导入放在函数内,函数在类的__del__方法内。

解决方案的"else raise"部分不会引发异常。来自python文档:"不会捕获onerror引发的异常。"docs.python.org/2/library/shutil.html_shutil.rmtree

我想说,使用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)

这几乎是正确的-Windows只支持stat.S_IWRITE(这也是您所希望的)-docs.python.org/library/os.html os.chmod

我测试过os.chmod(filename, stat.S_IWUSR)删除了只读标志,所以它可以在winxp上工作。考虑到这就是docs对stat.S_IWRITE所说的:"unix v7是s_iwusr的同义词"(docs.python.org/library/stat.html_stat.s_iwrite),我认为我的代码无论如何都是正确的。

很好,文件路径太长,这似乎是唯一的方法。建议提交或更改shutil.rmtree。

这应该是公认的答案。

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

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

shutil.rmtree(path,ignore_errors=False,οnerrοr=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,引发异常。请在此处输入代码

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

from subprocess import call

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

为了执行你想要的一切。

在Windows上调用rm -rf?我不这么认为。

很奇怪。我使用类似于Unix的Windows控制台仿真器(Cmder)。当我从控制台运行脚本时,subprocess.call方法可以工作,但如果我从默认的"命令提示"运行脚本,则不行。

你在投反对票之前试过了吗?我确认它在窗户下工作

@besil,是的,call('rm -rf"C:\\Temp\\tmp7cm15k\"', shell=True)导致'rm' is not recognized as an internal or external command, operable program or batch file.。

MH,我认为它对我有用,因为我使用cygwin作为终端模拟器,而不是命令提示符

@besil:将您的建议限定为在Cygwin或其他一些Windows移植的Unix shell下运行。

@理查德杰索普只是使用cygwin而不是windows命令提示符来启动python脚本。cygwin在路径中有"rm"和其他unix实用程序,因此当py脚本执行"call system rm"时,会有效地找到rm

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值