2010-02-10 2 views
1

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

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' 

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

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

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

Я проверил '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() 
+3

что это значит *, кажется, не работает *? вы получаете сообщение об ошибке? – SilentGhost

+0

Это не удастся, если какое-либо имя каталога включало пробелы (при вызове os.system), или если текущий каталог на входе не был 'rootDir'. Вы получаете ошибку, и если да, то что и где? Или неожиданное поведение, и если да, то что и где? Некоторые 'print' дадут нам больше информации (в настоящее время вы даете нам около 0 бит ;-). –

+0

Общее предложение/предупреждение при вызове системы, особенно когда задействован «rm». Дайте вашей функции вариант с сухим запуском, который по умолчанию является True, который печатает системные команды, которые он будет запускать. – MattH

ответ

9
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" 
+0

+1 для затвора. Предпочтительно os.system ("rm -rf") –

1

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

1
  • Что делает drop_sandbox()? (Функция, которую вы нам дали, - delete_sandbox()) Возможно, вы имели в виду, что это рекурсивная функция и использовали неправильное имя функции.
  • Является ли rootDir глобальной переменной? Возможно, вы имели в виду os.chdir("..")
  • Что содержит rootDir? os.listdir дает относительные пути. Если rootDir является базой для вашего поиска, то указанные вами каталоги могут не работать. Хуже: если они это сделают, вы можете удалить что-то, что вы все еще хотите.

Кроме того, shutil пакет имеет rmtree функцию, которую вы могли бы хотеть смотреть.

0

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

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

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

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) 

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

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

+0

'exception_list = []' на уровне класса является ошибкой. Этот список разделяется между экземплярами. Чтобы избежать этого, всегда необходимо установить атрибуты Mutable в '__init__' (обычно это полезно сделать для всех атрибутов, которые вы всегда собираетесь устанавливать/использовать на экземплярах и использовать атрибуты уровня класса только тогда, когда вы действительно хотите получить к ним доступ на уровне класса) – ThiefMaster

+0

Кроме того, 'is' неверно для сравнения. Использовать '==' для этого - это проверка идентичных объектов, и это чистое совпадение и деталь реализации, которая работает для определенных коротких строк. – ThiefMaster

Смежные вопросы