83

What is the easiest way to do the equivalent of rm -rf in Python?

Marco Bonelli
  • 55,971
  • 20
  • 106
  • 115
Josh Gibson
  • 20,110
  • 26
  • 64
  • 63
  • 1
    Possible 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 Answers7

92
import shutil
shutil.rmtree("dir-you-want-to-remove")
Greg Hewgill
  • 890,778
  • 177
  • 1,125
  • 1,260
Josh Gibson
  • 20,110
  • 26
  • 64
  • 63
44

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

Gabriel Grant
  • 5,225
  • 2
  • 30
  • 38
  • 2
    This 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
  • Good catch, @pevik -- fixed it. Thanks! – Gabriel Grant Oct 05 '15 at 13:36
  • 1
    This 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
3
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).

pevik
  • 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
0
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)
Banghua Zhao
  • 1,478
  • 1
  • 12
  • 22
Pogramist
  • 35
  • 3
  • Удаляет папку с файлами или файл, даже если стоит атрибут "Только чтение" Deletes a folder with files or a file, even if the attribute "Read only" – Pogramist May 28 '17 at 10:11
  • 1
    In English, please: _Deletes a folder with files or a file, even if attributed "Read only"_ – JosefZ May 28 '17 at 10:11
  • 1
    It was translater, i don't know english well)) – Pogramist May 28 '17 at 11:03
0

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+") 

source: https://stackoverflow.com/a/2769090/6345724

Dan
  • 298
  • 3
  • 18
-2

shutil.rmtree() is right answer, but just look at another useful function - os.walk()

maxp
  • 5,214
  • 6
  • 27
  • 29
-9

Just do this:

import os
dirname = "path_to_directory_to_remove"
os.system("rm -rf %s" % dirname)