Estoy tratando de aprender Python-Watchdog, pero estoy un poco confundido por qué el trabajo que configuré se ejecuta más de una vez. Entonces, aquí está mi puesta a punto:
#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
El observador se configura así:
#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()
Y finalmente, las acciones así:
#actions.py import os import subprocess def run_something(): output = subprocess.check_output(['./run.sh']) print output return None
..where ./run.sh
es solo un script de shell que me gustaría ejecutar cuando se encuentra un archivo con una extensión .done
en /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)"
Sin embargo, cuando touch job.done
un python observer.py
y luego hago un touch job.done
de touch job.done
en /path/to/some/directory/bin
, veo que mi script de shell ./run.sh
ejecuta tres veces y no uno.
Estoy confundido por qué esto se ejecuta tres veces y no solo una vez ( job.done
archivo job.done
en mi script de bash)
Para depurar los scripts de watchdog, es útil imprimir qué watchdog está viendo como eventos. Un comando de edición de archivo o CLI, como el touch
, puede generar múltiples eventos de vigilancia. Por ejemplo, si inserta una statement de impresión:
class ChangeHandler(FileSystemEventHandler): def on_any_event(self, event): print(event)
para registrar cada evento, ejecutando
% touch job.done
genera
2014-12-24 13:11:02 - 2014-12-24 13:11:02 - 2014-12-24 13:11:02 -
src_path
había dos eventos con src_path
terminaba en job.done
. Así,
if getext(event.src_path) == '.done': run_something()
se ejecuta dos veces porque hay un FileCreatedEvent
y un FileModifiedEvent
. Es posible que sea mejor que solo supervise FileModifiedEvent
s.