답변:
inotifywait
예를 들어을 사용 하는 것을 고려해야합니다 .
inotifywait -m /path -e create -e moved_to |
while read path action file; do
echo "The file '$file' appeared in directory '$path' via '$action'"
# do something with the file
done
우분투에서는 패키지 inotifywait
로 제공됩니다 inotify-tools
. 버전 3.13부터 (Ubuntu 12.04에서 현재) inotifywait
는 -f 옵션없이 파일 이름을 포함합니다. 이전 버전은 강제해야 할 수도 있습니다. 주목 해야 할 것은 이벤트 필터링을 수행하는 가장 좋은 방법은 -e
옵션 inotifywait
입니다. 또한 read
명령은 위치 출력을 여러 변수에 지정하여 사용하거나 무시하도록 선택할 수 있습니다. grep / sed / awk를 사용하여 출력을 사전 처리 할 필요가 없습니다.
inotifywait
내가 원하는 그냥 뭐이었다.
The '--filename' option no longer exists. The option it enabled in earlier versions of inotifywait is now turned on by default.
그래서, 당신은 할 필요가 inotifywait -m /path -e create |
나는 시도하고이 답변을 편집 할거야.
fswatch
. 나는 그것을 쓰지 않았지만 오픈 소스이며 그것을 사용합니다.
incron
관리하기 쉽기 때문에 선호합니다 . 기본적으로 이는 서비스를 활용 inotify
하며 파일 변경 작업을 기반으로 조치를 취하도록 구성을 설정할 수 있습니다.
전의:
<directory> <file change mask> <command or action> options
/var/www/html IN_CREATE /root/scripts/backup.sh
여기에서 전체 예를 볼 수 있습니다 : http://www.cyberciti.biz/faq/linux-inotify-examples-to-replicate-directories/
방금 이것을 요리하고 검사 사이에 파일이 누락 될 가능성을 제외하고는 큰 문제가 없습니다.
while true
do
touch ./lastwatch
sleep 10
find /YOUR/WATCH/PATH -cnewer ./lastwatch -exec SOMECOMMAND {} \;
done
파일 처리에 시간이 오래 걸리지 않으면 새 파일을 놓치지 않아야합니다. 당신은 또한 활동을 배경으로 할 수 있습니다 ... 그것은 방탄은 아니지만 inotify와 같은 외부 도구없이 일부 목적을 제공합니다.
inotify
사용할 수없는 경우 최상의 솔루션 입니다. -type f
파일 만 필터링하기 위해 추가 합니다. 그렇지 않으면 폴더도 반환됩니다.
-f filename
옵션이 훌륭합니다. 따라서 남은 유일한 질문은 재부팅 할 때 시작하는 방법입니다. 이것을 태양열 발전소와 함께 사용하여이 os.system("ssh me@mysystem ' ( touch /home/me/alarms/low24 ) '")
파일을 만들면 마스터 컴퓨터가 espeak
저전압 을 사용 하고 발표하게됩니다. 그것은 이미 나에게 이메일을 보내지 만 내 시스템은 이미 시간의 맨 위에 시간을 말하므로 나머지는 모두 있습니다. askubuntu.com/questions/977613/…
당신은 watch
당신의 스크립트에서 사용할 수 있습니다
watch -n 0.1 ls <your_folder>
폴더를 모니터링하고 0.1 초마다 모든 것을 나열합니다
약점
실시간이 아니므로 파일이 0.1 초 이내에 생성 및 삭제 된 경우 작동하지 않으며 watch
최소 0.1 초만 지원합니다.
대상 폴더 ( isempty
편의를 위해 전화 할 것입니다 )가 비어 있고 하나 이상의 파일이 드롭되기를 기다리고 있다고 가정합니다 .
다음 명령을 사용할 수 있습니다.
ls -1A isempty | wc -l
폴더가 여전히 비어 있는지 확인하기 위해 새 파일이 없으면 0을 반환 isempty
하거나 폴더가 여전히 비어 있으면 0보다 큰 값을 반환합니다 (실제로는 숫자 폴더에있는 파일 수).
그것은 바보 같은 if / then 테스트가 나머지 작업을 수행 할 수 있다고 말했습니다.
if [ $(ls -1A isempty | wc -l) -gt 0 ] ; then do_something ; fi
물론 do_something
함수는 isempty
폴더 내에서 파일을 조작 한 다음 처리 후 폴더 자체에서 파일 을 제거해야합니다.
crontab에 다음과 같은 줄을 추가하면 1 분에 한 번씩 검사가 실행 do_something
되고 폴더가 비어 있지 않은 경우 작업 이 트리거됩니다 .
* * * * * if [ $(ls -1A isempty | wc -l) -gt 0 ] ; then do_something ; fi
새 파일을 감지하려면 해당 파일을 처리하고 마지막에 진행된 파일을 삭제하면 systemd.path 를 사용할 수 있습니다 . 이 방법은 inotify를 기반으로합니다. DirectoryNotEmpty 옵션이 있으므로 systemd는 디렉토리의 파일을 감지 할 때 항상 스크립트를 실행할 수 있습니다. 진행된 파일을 삭제할 수 있고 스크립트가 디렉토리를 비워 둔 경우에만 작동한다는 것을 기억해야합니다.
먼저 mymonitor.service 파일을 준비하십시오.
[Unit]
Description=Start the script
[Service]
Type=oneshot
ExecStart=/path/to/your/script
다음으로 mymonitor.path로 이동하여 경로를 정의하십시오.
[Unit]
Description= Triggers the service
[Path]
DirectoryNotEmpty=/path/to/monitor
[Install]
WantedBy=multi-user.target
.path 파일 이름이 서비스 이름과 동일하면 .path 파일에 서비스 이름을 지정할 필요가 없습니다.
더미에 대한 파일 액세스 모니터링을 기반으로합니다.
entr
사용하는 entr
것이 새로운 방법입니다 (크로스 플랫폼). 참고 entr
는 폴링을 사용하지 않으므로 많은 대안에 비해 큰 이점이 있습니다.
폴링을 사용
kqueue(2)
하거나inotify(7)
피합니다.entr
빠른 피드백과 자동 테스트를 자연스럽고 완전히 평범하게하도록 작성되었습니다.
BSD에서는 pledge(2)
당신은 그것을 설치할 수 있습니다
apt-get install entr
dnf install entr
다음을 사용하여 새로 추가 한 디렉토리를 추적 할 수 있습니다.
while $(true); do
# echo ./my_watch_dir | entr -dnr echo "Running trigger..."
echo ./my_watch_dir | entr -dnr ##MY COMMAND##
done;
옵션은 (문서에서),
-d
입력으로 제공된 일반 파일의 디렉토리를 추적하고 새 파일이 추가되면 종료하십시오. 이 옵션을 사용하면 디렉토리를 명시 적으로 지정할 수도 있습니다. 이름이 '.'로 시작하는 파일 무시됩니다.-n
비 대화식 모드에서 실행하십시오. 이 모드에서 entr은 TTY를 읽거나 속성을 변경하지 않습니다.-r
지속적 하위 프로세스를 다시로드하십시오. 표준 작동 모드와 마찬가지로 종료되는 유틸리티는 파일 시스템 또는 키보드 이벤트가 처리 될 때까지 다시 실행되지 않습니다.SIGTERM
유틸리티를 다시 시작하기 전에 종료하는 데 사용됩니다. 쉘 스크립트가 신호를 마스킹하지 못하도록 프로세스 그룹이 작성됩니다.entr
소켓과 같은 자원이 닫혔는지 확인하기 위해 유틸리티가 종료 될 때까지 기다립니다. TTY 제어는 하위 프로세스로 전송되지 않습니다.
배쉬는 이것을 쉽게 할 수 없습니다. 기본적으로 폴더의 모든 파일 목록을 가져와 주기적으로 새 목록을 가져 와서 비교하여 변경된 내용을 확인해야합니다.
당신이 찾고있는 것을 inotify라고합니다. 그것은 리눅스 커널에 내장되어 있으며 기본적으로 inotify가 돌아와서 foobar라는 새로운 파일이 있다고 지적하는 무언가가 일어나기를 기다리고 있습니다.
원하는 것을 달성하려면 perl과 같은 것으로 전환하고 Linux :: Inotify2를 사용해야합니다 (파이썬은 inotify도 지원하지만, 나는 perl 사람입니다).
이것은 cygwin과 Linux에서 작동합니다. 파일을 작성하는 이전 솔루션 중 일부는 디스크를 손상시킵니다. 이 scipt에는 그 문제가 없습니다 :
SIG=1
SIG0=$SIG
while [ $SIG != 0 ] ; do
while [ $SIG = $SIG0 ] ; do
SIG=`ls -1 | md5sum | cut -c1-32`
sleep 10
done
SIG0=$SIG
ls -lrt | tail -n 1
done
다음에 예를의 축약 버전 에 유래 특정 디렉토리의 모니터링을 필요로 내 프로젝트 중 하나에 테스트와 통합했습니다.
Var_dir="${1:-/tmp}"
Var_diff_sleep="${2:-120}"
Var_diff_opts="--suppress-common-lines"
Func_parse_diff(){
_added="$(grep -E '>' <<<"${@}")"
if [ "${#_added}" != "0" ]; then
mapfile -t _added_list <<<"${_added//> /}"
_let _index=0
until [ "${#_added_list[@]}" = "${_index}" ]; do
_path_to_check="${Var_dir}/${_added_list[${_index}]}"
if [ -f "${_path_to_check}" ]; then
echo "# File: ${_path_to_check}"
elif [ -d "${_path_to_check}" ]; then
echo "# Directory: ${_path_to_check}"
if [ -p "${_path_to_check}" ]; then
echo "# Pipe: ${_path_to_check}"
fi
let _index++
done
unset _index
fi
}
Func_watch_bulk_dir(){
_current_listing=""
while [ -d "${Var_dir}" ]; do
_new_listing="$(ls "${Var_dir}")"
_diff_listing="$(diff ${Var_dec_diff_opts} <(${Var_echo} "${_current_listing}") <(${Var_echo} "${_new_listing}"))"
if [ "${_diff_listing}" != "0" ]; then
Func_parse_diff "${_diff_listing}"
fi
_current_listing="${_new_listing}"
sleep ${Var_diff_sleep}
done
}
다음 은 sshfs 마운트 지점에있는 파일이나 디렉토리를 자동으로 해독하기 위해 수정 된 버전의 스크립트 를 사용 하는 스크립트에 대한 링크입니다 . 앞서 언급 한 프로젝트.