2014-12-24 3 views
3

Я пытаюсь изучить python-watchdog, но я немного смущен, почему задание, которое я настраивал, запускается более одного раза. Итак, вот мой набор вверх:python watchdog запускается более одного раза

#handler.py 
import os 
from watchdog.events import FileSystemEventHandler 
from actions import run_something 

def getext(filename): 
    return os.path.splitext(filename)[-1].lower() 

class ChangeHandler(FileSystemEventHandler): 

    def on_any_event(self, event): 

     if event.is_directory: 
      return 
     if getext(event.src_path) == '.done': 
      run_something() 
     else: 
      print "event not directory.. exiting..." 
      pass 

наблюдатель устанавливается следующим образом:

#observer.py 
import os 
import time 
from watchdog.observers import Observer 
from handler import ChangeHandler 

BASEDIR = "/path/to/some/directory/bin" 

def main(): 

    while 1: 

     event_handler = ChangeHandler() 
     observer = Observer() 
     observer.schedule(event_handler, BASEDIR, recursive=True) 
     observer.start() 
     try: 
      while True: 
       time.sleep(1) 
     except KeyboardInterrupt: 
      observer.stop() 
     observer.join() 

if __name__ == '__main__': 
    main() 

и, наконец, действия, как так:

#actions.py 
import os 
import subprocess 

def run_something(): 
    output = subprocess.check_output(['./run.sh']) 
    print output 
    return None 

..where ./run.sh является просто сценарий оболочки, который я хотел бы запустить, когда файл с расширением .done находится на /path/to/some/directory/bin

#run.sh 
#!/bin/bash 
echo "Job Start: $(date)" 
rm -rf /path/to/some/directory/bin/job.done # remove the .done file 
echo "Job Done: $(date)" 

Однако, когда я выпустить python observer.py, а затем сделать touch job.done на /path/to/some/directory/bin, я вижу, что мой сценарий оболочки ./run.sh проходит три раза, а не один ..

Я смущен, почему это работает в три раза, а не только один раз (Я удаляю файл job.done в моем сценарии bash)

+1

«Пока 1» и «Пока правда» - это плохой код, и я думаю, что в вашем коде это даже не нужно, поскольку вызовы «join» обычно блокируются до тех пор, пока условие не будет выполнено. В какой-то момент ваш код будет блокироваться бесконечно, создавая процесс зомби, который тратит системные ресурсы. – specializt

+0

Собственно, я взял код прямо из учебника: http://ginstrom.com/scribbles/2012/05/10/continuous-integration- in-python-using-watchdog/Я теперь удалил как «1», так и «While true» из кода. Еще раз спасибо за подсказку. – JohnJ

ответ

3

Чтобы отладить скрипты сторожевого таймера, полезно распечатать, что сторожевой сторож видит как события. Одна команда редактирования файла или CLI, такая как touch, может привести к нескольким сторожевым событиям. Например, если вставить печать заявление:

class ChangeHandler(FileSystemEventHandler): 

    def on_any_event(self, event): 
     print(event) 

регистрировать каждое событие, бег

% touch job.done 

генерирует

2014-12-24 13:11:02 - <FileCreatedEvent: src_path='/home/unutbu/tmp/job.done'> 
2014-12-24 13:11:02 - <DirModifiedEvent: src_path='/home/unutbu/tmp'> 
2014-12-24 13:11:02 - <FileModifiedEvent: src_path='/home/unutbu/tmp/job.done'> 

Выше были два события с src_path заканчивая job.done. Таким образом,

if getext(event.src_path) == '.done': 
     run_something() 

работает в два раза, потому что есть FileCreatedEvent и FileModifiedEvent. Возможно, вам будет лучше контролировать только FileModifiedEvent s.

+0

Thats просто потрясающе - большое спасибо за это - теперь я использую 'on_created', чтобы просто контролировать только что созданные файлы (так как я все равно удаляю' job.done' на мой скрипт bash). Работает так, как ожидалось! принял ваш ответ :) – JohnJ

+0

Как вы думаете, мне лучше искать 'FileCreatedEvent', а не' FileModifiedEvent'? – JohnJ

+0

Ну, я не думаю, что это важно в этом случае. Я предложил «FileModifiedEvent» только потому, что это происходит последним, так что вы знаете, что было записано в файл. В этом случае звучит так, будто вы не читаете файл, так что это не имеет значения. – unutbu