inotify로 파일 변경 실시간 감시하기

리눅스 시스템의 특정 디렉토리 내의 파일 변화를 감지하려면 기본적으로 떠오르는 생각이 있다.
1. 일정 주기로 디렉토리를 스캔한다.
2. 기억해 놓은 이전 상태와 현재 상태를 비교한다.
3. 변경점을 찾아 처리한다.
이러한 방법은 상태의 변화를 비교하는 것 또한 어렵지만, 디렉토리의 구조가 복잡해지고, 파일이 많아질 경우에는 변경이 발생하지 않았더라도 스캔 작업을 매 주기 마다 진행해야 하므로 시스템에 부하를 많이 안겨주게 된다. 또한, 동작 주기가 짧으면 짧을 수록 부하가 커진다.
이러한 점을 보완할 수 있는 방법이 있다. inotify는 리눅스 커널 레벨에서 지원하는 기능으로, 해당 디렉토리 내부에 변화가 감지될 경우 stream으로 event를 발생시킨다. 따라서 사용자는 매번 디렉토리 전체를 스캔할 필요가 없이, stream을 열고 event가 발생했는지만 감지하면 된다.
위키백과 “inotify” (http://ko.wikipedia.org/wiki/Inotify)

Windows 시스템은 inotify 외에 별도의 감시 API가 존재한다.

php에서도 시스템의 inotify 기능을 이용할 수 있도록 기본 함수가 마련되어 있다.
글을 쓰는 변 모씨의 경우, 특정 디렉토리에 이미지 파일들을 DB를 통해 관리하려는 목적으로 inotify를 사용하게되었다.
즉, 이미지의 추가 정보(크기, 체크섬 등)를 DB에 저장하고 있으므로, 이미지 파일이 생성되거나 삭제되면 DB에 반영하기 위해 해당 변경사항을 감지하고 있어야만 한다.
다음은 인터넷 상의 샘플 소스를 짜집기하여 만든 코드이다.

코드상의 이벤트가 어떤 경우에 발생하는지 알면 로직 작성에 도움이 될 것 같다.
다음은 시스템 상에서 특정 동작이 일어날 때 발생하는 이벤트를 정리해 놓은 것이다.
ls로 조회할 때,
    IN_OPEN
    IN_CLOSE_NOWRITE
ssh client에서 rz로 파일 업로드할 때,
    IN_CREATE
    IN_OPEN
    IN_MODIFY
    IN_MODIFY
    IN_MODIFY
    IN_CLOSE_WRITE
    IN_ATTRIB
FTP에서 업로드 할 때,
    IN_CREATE
    IN_OPEN
    IN_MODIFY
    IN_MODIFY
    IN_MODIFY
    IN_CLOSE_WRITE
touch로 파일 생성할 때
    IN_CREATE
    IN_OPEN
    IN_ATTRIB
    IN_CLOSE_WRITE
감시 중인 폴더 내에서 이동할 때,
    IN_MOVED_FROM src_filename
    IN_MOVED_TO dst_filename
외부에서 폴더 내로 이동할 때,
    IN_MOVED_TO dst_filename
파일 지울 때,
    IN_DELETE
chown 소유권 변경할 때,
    IN_ATTRIB
디렉토리를 만들때
    IN_CREATE
결론적으로, 파일이 생성되거나 수정된 후에는 항상 IN_CLOSE_WRITE 가 호출되는 것을 알 수 있다.
파일이 변경되는 것에 대한 로직은 IN_CLOSE_WRITE 에 작성하면 된다.
파일이 이동되는 것은 IN_MOVED_FROM, IN_MOVED_TO 등에 작성하면 될 것 같다.
감시되는 디렉토리 내에 새로 디렉토리가 생성된다면, 생성된 디렉토리도 inotify에 등록을 해줘야 그 안에 변경되는 파일도 감시를 할 수가 있다. 물론 디렉토리가 삭제 될 때는 inotify에서 제외해야 한다.
도큐멘트 에 올린 글 태그됨: , , ,

댓글 남기기