shutil.rmtree fails on Windows with 'Access is denied'
Solution 1
Check this question out: What user do python scripts run as in windows?
Apparently the answer is to change the file/folder to not be read-only and then remove it.
Here's onerror()
handler from pathutils.py
mentioned by @Sridhar Ratnakumar in comments:
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
# Is the error an access error?
if not os.access(path, os.W_OK):
os.chmod(path, stat.S_IWUSR)
func(path)
else:
raise
Solution 2
I'd say implement your own rmtree with os.walk that ensures access by using os.chmod on each file before trying to delete it.
Something like this (untested):
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)
Solution 3
Well, the marked solution did not work for me... did this instead:
os.system('rmdir /S /Q "{}"'.format(directory))
Solution 4
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
If ignore_errors is set, errors are ignored; otherwise, if onerror is set, it is called to handle the error with arguments (func, path, exc_info) where func is os.listdir, os.remove, or os.rmdir; path is the argument to that function that caused it to fail; and exc_info is a tuple returned by sys.exc_info(). If ignore_errors is false and onerror is None, an exception is raised.enter code here
Related videos on Youtube
![Sridhar Ratnakumar](https://i.stack.imgur.com/gVHrv.jpg?s=256&g=1)
Sridhar Ratnakumar
Updated on July 05, 2022Comments
-
Sridhar Ratnakumar almost 2 years
In Python, when running
shutil.rmtree
over a folder that contains a read-only file, the following exception is printed: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'
Looking in File Properties dialog I noticed that
af.msg
file is set to be read-only.So the question is: what is the simplest workaround/fix to get around this problem - given that my intention is to do an equivalent of
rm -rf build/
but on Windows? (without having to use third-party tools like unxutils or cygwin - as this code is targeted to be run on a bare Windows install with Python 2.6 w/ PyWin32 installed)-
jfs about 14 years
shutil.rmtree
usesos.remove
to remove files.os.remove
removes read-only files just fine (at least on Unix).os.remove
can't remove file on Windows if it is in use. -
Stevoisiak about 6 years
-
Ali_Sh over 2 yearsAs I experienced, perhaps, this error will be appeared if the directory is open and you run the the code and is related to removing process, not the creation step.
-
-
Daniel G about 14 yearsThis is nearly right - Windows only supports
stat.S_IWRITE
(which is what you want anyway) - docs.python.org/library/os.html#os.chmod -
Sridhar Ratnakumar about 14 yearsHeh. I just discovered the
onerror
handler at voidspace.org.uk/downloads/pathutils.py -
Sridhar Ratnakumar about 14 years.. discovered that via trac.pythonpaste.org/pythonpaste/ticket/359
-
Epcylon about 14 yearsI did test that
os.chmod(filename, stat.S_IWUSR)
removed the read-only flag, so it does work on WinXP. And considering this is what the docs say aboutstat.S_IWRITE
: "Unix V7 synonym for S_IWUSR" (docs.python.org/library/stat.html#stat.S_IWRITE), I'm thinking my code is right anyway. -
Pakman over 10 yearsEven though the comments for this answer state 'change the file/folder to not be read-only', I still received access denied on read-only folders. This implementation worked, though.
-
Adam almost 10 yearsA word of warning to those copy-pasting this function as is, move the
import stat
out of the function. I was receivingRuntimeError: sys.meta_path must be a list of import hooks
when I'd left the import within the function AND the function was within the__del__
method of a class. -
Anthony about 9 yearsGreat, with file paths that are too long this seems like the only way. A recommendation to commit to or change shutil.rmtree perhaps.
-
GDICommander almost 9 yearsThe "else raise" part of the solution will not raise the exception. Coming from the Python documentation: "Exceptions raised by onerror will not be caught." docs.python.org/2/library/shutil.html#shutil.rmtree
-
omerfarukdogan over 5 yearsCalling
rm -rf
on Windows? I don't think so. -
Dustin Michels over 5 yearsVery strange. I use a unix-like console emulator for Windows (cmder). The
subprocess.call
approach works when I run the script from that console, but not if I run it from the default "Command Prompt" -
besil over 5 yearsHave you tried before downvoting? I confirm it works under Windows
-
omerfarukdogan over 5 years@besil, yes,
call('rm -rf "C:\\Temp\\tmp7cm15k\\"', shell=True)
results in'rm' is not recognized as an internal or external command, operable program or batch file.
-
besil over 5 yearsmh, I think it works for me because I use Cygwin as terminal emulator instead of command prompt
-
Richard Jessop about 5 years@besil: qualify your suggestion to running under cygwin or some other windows-ported unix shell.
-
besil about 5 years@RichardJessop just use Cygwin instead of Windows Command Prompt for launching your python script. Cygwin has 'rm' and other unix utilities in the path, so when the py script do 'call system rm', rm is effectively found
-
Helping Hands over 4 yearsThis removed the directory itself. Can you please tell how to remove all dir and files inside a directory? For example if I give path : myproject/dir1/ then it removes dir1 but I want to delete everything which is under dir1.
-
Alper over 3 yearsThis works with
stat.S_IWRITE
in python 2.7 in windows 10 for read-only files. -
Mario Orlandi over 3 yearsNice, but fails in presence of nested subfolders ... unless you recourse deletion by replacing "os.rmdir(os.path.join(root, name))" with "rmtree(os.path.join(root, name))"
-
Epcylon over 3 yearsHave you tried it and gotten an error? The code walks the tree from the bottom up, so all directories are empty by the time we run
os.rmdir
on them, assuming everything else works. -
Maryam Bahrami about 3 yearsBe very careful using this function. This function goes to every subfolder and delete the files in there.
-
Epcylon about 3 yearsMaryam Bahrami: Yes, that is the purpose of the rmtree function. If this is not what you want, why are you using it?
-
Mawg says reinstate Monica about 2 yearsPersonally, I find it easier just to delete the directory and recreate it (although you do lose the timestamp that way)