chrisg
chrisg

Reputation: 41655

Delete Old directories in Python

I have several directories and I want directories over 7 days old to be deleted. I have code already implemented but It doesn't seem to be working. Can anyone see where I am going wrong?

def delete_sandbox():

    for directories in os.listdir(os.getcwd()): 

        if not os.path.isdir(directories) or not os.stat(directories).st_ctime < time.time()-(7*24*3600): 
            continue
        os.chdir(directories)
        drop_sandbox()
        os.chdir(rootDir)
        os.system("sudo rm -rf "+directories)
        print 'Folders older than 7 days old dropped and removed'

Thanks for any help

The folders sandboxes drop but do not delete. I want the program to go into each one of these folders, drop the sandbox, chnage back to the root directory and delete all the old directories. When I do this the folders still exist.

Also this function worked when I had the directories deleted by the string date stored in the folder name. But now that I am trying to get the timestamp it has stopped working.

I have tested the 'rm -rf'+directories and it does not delete old folders. When I try shutil.rmtree I get the error message:

Traceback (most recent call last):
  File "yep.py", line 21, in <module>
    delete_sandbox()
  File "yep.py", line 18, in delete_sandbox
    shutil.rmtree(directories)
  File "/home/build/workspace/downloads/Python-2.6.4/Lib/shutil.py", line 208, in rmtree
    onerror(os.listdir, path, sys.exc_info())
  File "/home/build/workspace/downloads/Python-2.6.4/Lib/shutil.py", line 206, in rmtree
    names = os.listdir(path)
OSError: [Errno 2] No such file or directory: 'Debug'

Is there any other way to delete these folders?

I got it working, I used shutil.rmtree and all seemed to worked. Thanks for any help. The amended code is:

def delete_sandbox():

    for directories in os.listdir(os.getcwd()): 

        if not os.path.isdir(directories) or not os.stat(directories).st_ctime < time.time()-(sbox_age): 
            continue
        os.chdir(directories)
        drop_sandbox()
        os.chdir(rootDir)
        shutil.rmtree(directories)
        print 'Sandboxes older than 7 days old dropped and removed'

delete_sandbox()

Upvotes: 2

Views: 9491

Answers (4)

Justus Wingert
Justus Wingert

Reputation: 502

While the general idea of the accepted answer is sound the implementation has a few points that are not.

  1. Variable names aren't charged by the character.
  2. Please do not overwrite python methods like dir()

Since I needed a bit more functionality I took your idea and built this:

class CompRM(object):
    exception_list = []
    path = None
    comparator = None
    comparator_target = None
    comparator_delete_condition = None

    delete_directories = False
    delete_files = False

    def __init__(self, target_path, comparator, comparator_target='st_mtime', comparator_delete_condition='>', delete_directories=False, delete_files=False):
        self.path = target_path
        self.comparator = comparator
        self.comparator_target = comparator_target
        self.comparator_delete_condition = comparator_delete_condition

        for directory_path, directory_names, file_names in os.walk(self.path):
            if delete_directories is True:
                self.walk_names(directory_path, directory_names)
            if delete_files is True:
                self.walk_names(directory_path, file_names)

        if len(self.exception_list) > 0:
            raise Exception({'message': 'Encountered exceptions while deleting.', 'debug': self.exception_list})

    def walk_names(self, directory_path, names):
        for _name in names:
            _path = os.path.join(directory_path, _name)
            _stat = os.stat(_path)
            _value = getattr(_stat, self.comparator_target)
            if self.delete_condition_met(_value):
                self.safe_remove(_path)

    def delete_condition_met(self, value):
        if self.comparator > value and self.comparator_delete_condition is '>':
            return True
        if self.comparator < value and self.comparator_delete_condition is '<':
            return True
        return False

    def safe_remove(self, remove_path):
        print 'remove', remove_path
        shutil.rmtree(remove_path, onerror=self.register_exception)

    def register_exception(self, function, path, exception_info):
        self.exception_list.append({
            function: function,
            path: path,
            exception_info: exception_info,
        })

You can call it like this:

comprm = CompRM('/tmp', time.time() - 60*60*24*7, comparator_target='st_ctime', delete_files=True)

Where comparator_target is the attributename in os.stat() that is taken for comparison.

Regards, Justus

Upvotes: 0

ghostdog74
ghostdog74

Reputation: 342363

import os
import time
import shutil
numdays = 86400*7
now = time.time()
directory=os.path.join("/home","path")
for r,d,f in os.walk(directory):
    for dir in d:
         timestamp = os.path.getmtime(os.path.join(r,dir))
         if now-numdays > timestamp:
             try:
                  print "removing ",os.path.join(r,dir)
                  # shutil.rmtree(os.path.join(r,dir))  #uncomment to use
             except Exception,e:
                  print e
                  pass
             else: 
                  print "some message for success"

Upvotes: 11

3Doubloons
3Doubloons

Reputation: 2106

  • What does drop_sandbox() do? (The function you gave us is delete_sandbox()) Maybe you meant this to be a recursive function and used the wrong function name
  • Is rootDir a global variable? Perhaps you meant os.chdir("..")
  • What does rootDir contain? os.listdirgives relative paths. If rootDir is the base of your search, the directories you listed may not work. Worse: If they do, you might delete something you still want.

Additionally, the shutil package has a rmtreefunction you might want to look into.

Upvotes: 1

Alexander Torstling
Alexander Torstling

Reputation: 18898

os.listdir returns a list of strings, which are relative paths. When you chdir to rootdir, dependent on what rootDir is, these paths might not be valid anymore.

Upvotes: 1

Related Questions