2011-10-21 1 views
1

예, 리눅스 OS의 일부 디렉토리에서 파일 이벤트를 제거하고 추가해야합니다. 나는 inotify와 python wrappers 같은 라이브러리를 찾았지만, 분명 파이썬 코드를 사용하고 싶다면 os.listdir(path) 출력을보아야합니까? 아니면 그런 작업을 수행 할 수있는 방법이 있습니까?다른 저수준 라이브러리없이 파이썬을 사용하여 파일 시스템 이벤트 모니터링하기

+3

래퍼에 어떤 문제가 있습니까? – eumiro

+1

난 그냥 임무가 어디 ext libs를 사용하도록 허용되지 않은 일부 작업을 – User

답변

1

출처 : http://code.activestate.com/recipes/215418-watching-a-directory-tree-on-unix/

watch_directories() 함수는 삭제하거나 수정 시간이 변경이받을 파일을보고, 경로의 목록과 호출 오브젝트를하고 반복적으로 그 경로를 루트 디렉토리 트리를 통과 . 그런 다음 호출 할 수있는 객체에는 변경된 파일과 제거 된 파일이 포함 된 두 개의 목록이 전달됩니다. 당신이 데몬에 작업을 보낼 수있는 방법을 싶습니다하지만 같은 소켓이나 파이프로 일부 IPC 메커니즘을 사용하지 않을 경우

from __future__ import nested_scopes 

import os, time 

def watch_directories (paths, func, delay=1.0): 
    """(paths:[str], func:callable, delay:float) 
    Continuously monitors the paths and their subdirectories 
    for changes. If any files or directories are modified, 
    the callable 'func' is called with a list of the modified paths of both 
    files and directories. 'func' can return a Boolean value 
    for rescanning; if it returns True, the directory tree will be 
    rescanned without calling func() for any found changes. 
    (This is so func() can write changes into the tree and prevent itself 
    from being immediately called again.) 
    """ 

    # Basic principle: all_files is a dictionary mapping paths to 
    # modification times. We repeatedly crawl through the directory 
    # tree rooted at 'path', doing a stat() on each file and comparing 
    # the modification time. 

    all_files = {} 
    def f (unused, dirname, files): 
     # Traversal function for directories 
     for filename in files: 
      path = os.path.join(dirname, filename) 

      try: 
       t = os.stat(path) 
      except os.error: 
       # If a file has been deleted between os.path.walk() 
       # scanning the directory and now, we'll get an 
       # os.error here. Just ignore it -- we'll report 
       # the deletion on the next pass through the main loop. 
       continue 

      mtime = remaining_files.get(path) 
      if mtime is not None: 
       # Record this file as having been seen 
       del remaining_files[path] 
       # File's mtime has been changed since we last looked at it. 
       if t.st_mtime > mtime: 
        changed_list.append(path) 
      else: 
       # No recorded modification time, so it must be 
       # a brand new file. 
       changed_list.append(path) 

      # Record current mtime of file. 
      all_files[path] = t.st_mtime 

    # Main loop 
    rescan = False 
    while True: 
     changed_list = [] 
     remaining_files = all_files.copy() 
     all_files = {} 
     for path in paths: 
      os.path.walk(path, f, None) 
     removed_list = remaining_files.keys() 
     if rescan: 
      rescan = False 
     elif changed_list or removed_list: 
      rescan = func(changed_list, removed_list) 

     time.sleep(delay) 

if __name__ == '__main__': 
    def f (changed_files, removed_files): 
     print changed_files 
     print 'Removed', removed_files 

    watch_directories(['.'], f, 1) 

이 조리법에 유용합니다. 대신 데몬은 제출 디렉토리를보고 관찰 할 수 있으며 파일 또는 디렉토리를 제출 디렉토리에 놓아서 작업을 제출할 수 있습니다.

잠금은 고려되지 않습니다. watch_directories() 함수 자체는 실제로 잠금을 수행 할 필요가 없습니다. 한 번의 패스에서 수정이 누락 된 경우 다음 패스에서이를 확인합니다. 그러나 작업이 감시 된 디렉토리에 직접 작성되면 작업 파일이 절반 만 작성되는 동안 호출 가능 오브젝트가 실행되기 시작할 수 있습니다. 이를 해결하기 위해 lockfile을 사용할 수 있습니다. 호출자는 실행될 때 잠금을 획득해야하며 제출자는 새로운 작업을 추가 할 때 잠금을 획득해야합니다. 보다 간단한 접근법은 원자 단위의 rename() 시스템 호출에 의존하는 것입니다. 감시되지 않는 임시 디렉토리에 작업을 작성하고 파일이 완료되면 os.rename()을 사용하여 제출 디렉토리로 이동하십시오.