alejandro
alejandro

Reputation: 1274

shutil.rmtree to remove files only?

I am using shutil.rmtree to remove a directory, but other processes (that I don't control) that create files in that tree are failing to create the files because the directories don't exist. Is there something as easy as shutil.rmtree that only deletes files but preserves directory structure?

Upvotes: 8

Views: 9486

Answers (3)

Corey Goldberg
Corey Goldberg

Reputation: 60604

how about something like this:

import os

def rm_files_in_tree(dir):
    for root, dirs, files in os.walk(dir):
        for file in files:
            path = os.path.abspath(os.path.join(root, file))
            os.remove(path)

Upvotes: 0

zwol
zwol

Reputation: 140569

If you want to do it in one line, and you have GNU find, outsource:

subprocess.check_call(["find", "-H", directory, "!", "-type", "d", "-delete"])

This also has the advantage of having been very carefully coded by experts to avoid a number of race conditions which can allow a malicious process on the same system to trick your process into deleting something it shouldn't have. I don't think it's actually possible to avoid all of those races using os.walk; you need an API that lets you use unlinkat or fchdir.

Upvotes: 0

Adam Rosenfield
Adam Rosenfield

Reputation: 400244

I don't think there's a built-in function to do this, but you could easily do it yourself using os.walk():

for dirpath, dirnames, filenames in os.walk(my_directory):
    # Remove regular files, ignore directories
    for filename in filenames:
        os.unlink(os.path.join(dirpath, filename))

Upvotes: 6

Related Questions