Linux에서 디렉토리의 내용이 변경 될 때 자동으로 스크립트를 실행하는 방법은 무엇입니까?


17

새 파일을 특정 디렉토리에 복사 할 때마다 자동으로 스크립트를 실행하고 싶습니다. 다시 말해, 리눅스에서 변경 사항에 대한 디렉토리를 "감시"하고 변경에 대한 응답으로 무언가를 실행하는 방법이 있습니까?


이 토론은 모든 stackexchange 사이트에서 열렸습니다.) superuser.com/questions/181517/… stackoverflow.com/questions/4380527/… 등을 참조하십시오 .
masterxilo

답변:


17

운이 좋으면 데비안 기반 배포판을 사용할 수 apt-get install dnotify있습니다. 다른 배포판에는 비슷한 것이있을 수 있습니다 dnotify. 이름을 찾으십시오 .

dnotify는 Linux 커널 2.4.19+의 dnotify API를 기반으로하는 간단한 프로그램입니다. dnotify는 특정 디렉토리의 내용이 변경 될 때마다 지정된 명령을 실행할 수 있습니다. 명령 행에서 실행되며 모니터 할 하나 이상의 디렉토리와 디렉토리가 변경 될 때마다 실행할 명령의 두 가지 인수를 사용합니다. 옵션은 트리거 할 이벤트를 제어합니다. 디렉토리에서 파일을 읽은시기, 작성, 삭제 된시기 등.

자신의 프로그램 내에서이를 처리하려면 dnotify도 사용하려는 API입니다.


4
@MikeB는 인터넷 검색에서 제안한 것을 알지 못하고 대신 inotify를 사용하여 결국 그것을 대체합니다. 올바른 방향을 알려 주셔서 감사합니다. apt-get 설치 inotify-tools
GeneQ

7
@GeneQ, inotify는 dnotify를 대체했습니다.
David

1
젠투에서도 마찬가지입니다 :emerge inotify-tools
James Sneeringer

네, 말할 것입니다. 커널 2.4.19는 고대의 일종입니다. ;-) inotify는 갈 길입니다.
David Z

오 예 ... 나는 더 최근의 것을 잊었다 :)
MikeyB

12

inotify-tools를 사용하여 스크립트를 실행할 수 있습니다. 디렉토리에서 수정 된 파일, 새 파일 및 삭제 된 파일의 변경 사항을 감시 한 다음 스크립트를 실행합니다.

#!/bin/sh
while inotifywait -e modify -e create -e delete /home/me/code; do
    rsync [options] /home/me/code/ /media/nfs/code/ 
done

소스 디렉토리가 복사되는 동안 변경되면, inotifywait는이를 볼 수 없으며 복사가 완료된 후 추가 변경이있을 때까지 변경 사항이 복사되지 않음을 고려하십시오. 아마 문제는 아닙니다.
Raúl Salinas-Monteagudo

데몬 모드에서 어떻게 이것을 실행할 수 있습니까?
Chris F

4

incron 은 기본적으로 원하는 것입니다. inotify를 알림 메커니즘으로 사용하지만 (다른 사람들이 지적했듯이 dnotify를 대체 함) inotifywait 또는 유사한 것을 사용하여 연속적으로 실행되는 스크립트는 필요하지 않습니다 (명확하게도 incron 데몬은 항상 실행되고 있음). 시스템 전체 'crontabs'및 사용자 'crontabs'는 표준 cron과 유사한 방식으로 지원되지만 시간을 트리거로 지정하지 않고 inotify 이벤트 및 파일 / 디렉토리 이름이 사용됩니다.

incron은 우분투와 데비안을 포함한 많은 배포판에 패키지되어 있다고 생각합니다.



0

entr 은 내가 본 가장 단순하고 구성 가능한 파일 알림 도구입니다. 디렉토리가 아닌 파일을 보는 데 최적화되어 있지만 사례를 해결할 수도 있습니다.

추가 된 파일을 탐지하고 실행하려면 예를 들어 다른 도구와 결합하십시오 make. entr이름이나 그와 비슷한 것을 보내지 않고 단순히 실행하라는 말을 실행합니다.

디렉토리에서 추가 된 파일을 확인하려면 다음을 수행하십시오.

## entr exits with rc=0 when terminated
## rc=1 when watched files go away or don't exist to begin with
## rc=2 when new files arrive in watched directories
until echo /path/to/directory_to_watch | entr -d do_stuff
do sleep 1; done

기존 파일이 변경 될 때도 작동하려면 다음을 수행하십시오.

## Here's why it comes in handy that entr exits when new files are added --
## find gets re-run.
until find /path/to/directory_to_watch/ -path /path/to/directory_to_watch/* |
    entr -d do_stuff
do sleep 1; done

... 그리고 find파일이 추가되면 표현식이 다시 실행 되므로 루프 메커니즘이 유용합니다 .

더 나은 오류 처리를 원하고 추가 / 제거 된 파일 당 한 번만 실행되도록하려면 약간 까다로워 지지만 이러한 간단한 경우에는 훌륭합니다.


편집 : incron 과 같은 시스템 수준 에서이 작업을 수행 하려면 즐겨 사용하는 프로세스 관리자 ( s6 , runit , systemd 또는 sysvinit 와 같은 스크립트)를 추가 하고 루프를 건너 뛰십시오.

#!/bin/bash
exec entr -d do_stuff < <(find /path/to/directory_to_watch/ -path /path/to/directory_to_watch/*)

exec및 프로세스 대체가 ( <(...)제대로 신호 처리, 프로세스 관리자에서 실행하는 경우) 중요하다 (즉 비켜 쉘을 얻을 수 있습니다).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.