Удалить старые каталоги в Python - PullRequest
2 голосов
/ 10 февраля 2010

У меня есть несколько каталогов, и я хочу удалить каталоги старше 7 дней. Я уже реализовал код, но он не работает. Кто-нибудь может увидеть, где я иду не так?

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'

Спасибо за любую помощь

Песочницы папок удаляются, но не удаляются. Я хочу, чтобы программа вошла в каждую из этих папок, удалила песочницу, вернула chnage в корневой каталог и удалила все старые каталоги. Когда я делаю это, папки все еще существуют.

Также эта функция работала, когда мне удаляли каталоги по строковой дате, сохраненной в имени папки. Но теперь, когда я пытаюсь получить метку времени, она перестала работать.

Я протестировал 'rm -rf'+directories, и он не удаляет старые папки. Когда я пытаюсь shutil.rmtree, я получаю сообщение об ошибке:

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'

Есть ли другой способ удалить эти папки?

У меня все получилось, я использовал shutil.rmtree и все, казалось, работало. Спасибо за любую помощь. Измененный код:

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()

Ответы [ 4 ]

9 голосов
/ 10 февраля 2010
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"
1 голос
/ 10 февраля 2010
  • Что делает drop_sandbox()? (Функция, которую вы нам дали, delete_sandbox()) Возможно, вы имели в виду, что это рекурсивная функция, и использовали неправильное имя функции
  • Является ли rootDir глобальной переменной? Возможно, вы имели в виду os.chdir("..")
  • Что содержит rootDir? os.listdir дает относительные пути. Если rootDir является основой вашего поиска, перечисленные вами каталоги могут не работать. Хуже того: если они это сделают, вы можете удалить то, что вам по-прежнему нужно.

Кроме того, в пакете shutil есть функция rmtree, с которой вы, возможно, захотите ознакомиться.

1 голос
/ 10 февраля 2010

os.listdir возвращает список строк, которые являются относительными путями. Когда вы заходите в rootdir, в зависимости от того, что такое rootDir, эти пути могут быть недействительными.

0 голосов
/ 20 июня 2014

Хотя общая идея принятого ответа обоснована, реализация имеет несколько моментов, которых нет.

  1. Имена переменных не оплачиваются персонажем.
  2. Пожалуйста, не перезаписывайте методы Python, такие как dir ()

Так как мне нужно было немного больше функциональности, я взял вашу идею и построил это:

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,
        })

Вы можете назвать это так:

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

Где comptor_target - имя атрибута в os.stat (), которое берется для сравнения

С уважением, Юстус

...