What is the easiest way to do the equivalent of rm -rf in Python?
- 55,971
- 20
- 106
- 115
- 20,110
- 26
- 64
- 63
-
1Possible duplicate of [How do I remove/delete a folder that is not empty with Python?](http://stackoverflow.com/questions/303200/how-do-i-remove-delete-a-folder-that-is-not-empty-with-python) – Trevor Boyd Smith Nov 04 '16 at 19:23
7 Answers
import shutil
shutil.rmtree("dir-you-want-to-remove")
- 890,778
- 177
- 1,125
- 1,260
- 20,110
- 26
- 64
- 63
-
25While useful, rmtree isn't equivalent: it errors out if you try to remove a single file. – Gabriel Grant Mar 04 '12 at 23:28
-
For a more generic "remove non-empty directory" question where this answer would be a better fit see: http://stackoverflow.com/questions/303200/how-do-i-remove-delete-a-folder-that-is-not-empty-with-python – Ciro Santilli Путлер Капут 六四事 Dec 19 '14 at 07:41
-
`rm -rf non-existing-folder` works fine (it doesn't do anything), but your script will fail – Eric Duminil Nov 17 '19 at 21:22
While useful, rmtree isn't equivalent: it errors out if you try to remove a single file, which rm -f does not (see example below).
To get around this, you'll need to check whether your path is a file or a directory, and act accordingly. Something like this should do the trick:
import os
import shutil
def rm_r(path):
if os.path.isdir(path) and not os.path.islink(path):
shutil.rmtree(path)
elif os.path.exists(path):
os.remove(path)
Note: this function will not handle character or block devices (that would require using the stat module).
Example in difference of between rm -f and Python's shutils.rmtree
$ mkdir rmtest
$ cd rmtest/
$ echo "stuff" > myfile
$ ls
myfile
$ rm -rf myfile
$ ls
$ echo "stuff" > myfile
$ ls
myfile
$ python
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53)
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import shutil
>>> shutil.rmtree('myfile')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/shutil.py", line 236, in rmtree
onerror(os.listdir, path, sys.exc_info())
File "/usr/lib/python2.7/shutil.py", line 234, in rmtree
names = os.listdir(path)
OSError: [Errno 20] Not a directory: 'myfile'
Edit: handle symlinks; note limitations as per @pevik's comment
- 5,225
- 2
- 30
- 38
-
2This version does't work on symlinks to directories as python returns `True` on `os.path.isdir(symlink_to_directory)` – pevik Oct 01 '15 at 07:15
-
-
1This doesn't work for directories where the permissions disallow it, but you are root. At a shell prompt, you will get prompted "override rw------ for File.txt?" unless you use the -f flag. That works silently at the prompt while up above in python fails. – Matt Sep 13 '18 at 21:13
-
`os.remove` removes devices just fine; I just tried it. I don't understand the remarks about the code not working on device files and such. The POSIX syscall `unlink` doesn't distinguish between files and devices. – Kaz Oct 06 '19 at 00:03
import os
import shutil
def rm_r(path):
if not os.path.exists(path):
return
if os.path.isfile(path) or os.path.islink(path):
os.unlink(path)
else:
shutil.rmtree(path)
Slightly improved Gabriel Grant's version. This works also on symlinks to directories. Note: function does not handle Un*x character and block devices (it would require to use stat module).
- 4,091
- 3
- 28
- 39
-
You can probably handle devices by putting the `unlink` into the fallback case; do `rmtree` if you detect a directory. I.e. we don't have to specifically test for device node types. – Kaz Oct 05 '19 at 23:57
def delite(filepath):
import os, stat, sys
def intertwin(_list):
list1 = []
for i in _list:
list1 += i
return list1
allpath = os.walk(filepath)
walk = []
dirs = []
path = []
allfiles = []
for i in allpath:
walk.append(i)
for i in walk:
dirs.append(i[0])
for _dir in dirs:
os.chdir(_dir)
files = os.listdir(_dir)
files1 = []
for i in files:
files1.append(_dir + '\\' + i)
files = files1[:]
allfiles.append(files)
allfiles = intertwin(allfiles)
for i in allfiles:
os.chmod(i, stat.S_IRWXU)
allfiles.reverse()
os.chdir(sys.path[0])
for i in allfiles:
try:
os.remove(i)
except:
try:
os.rmdir(i)
except:
pass
os.chmod(filepath, stat.S_IRWXU)
try:
os.remove(filepath)
except:
os.rmdir(filepath)
allfiles.reverse()
os.chdir(sys.path[0])
for i in allfiles:
try:
os.remove(i)
except:
try:
os.rmdir(i)
except:
pass
os.chmod(filepath, stat.S_IRWXU)
try:
os.remove(filepath)
except:
os.rmdir(filepath)
- 1,478
- 1
- 12
- 22
- 35
- 3
-
Удаляет папку с файлами или файл, даже если стоит атрибут "Только чтение" Deletes a folder with files or a file, even if the attribute "Read only" – Pogramist May 28 '17 at 10:11
-
1In English, please: _Deletes a folder with files or a file, even if attributed "Read only"_ – JosefZ May 28 '17 at 10:11
-
1
A workaround for Windows where it blocks deletion of file is to truncate the file:
outputFile = open(r"filename.txt","w")
outputFile.truncate()
outputFile.close()
outputFile = open(r"filename.txt","a+")
- 298
- 3
- 18
shutil.rmtree() is right answer, but just look at another useful function - os.walk()
- 5,214
- 6
- 27
- 29
Just do this:
import os
dirname = "path_to_directory_to_remove"
os.system("rm -rf %s" % dirname)
- 63
- 3
-
2
-
2
-
1
-
2dangerous and platform dependent, but works, in the case where "-f" is required. None of the solutions above, except this one actually work for the "-f" required case. – Matt Sep 13 '18 at 20:37