디렉터리의 파일 변경 사항을 감지하는 Bash 스크립트

디렉터리의 파일 변경 사항을 감지하는 Bash 스크립트

디렉터리의 파일이 2초 간격 내에 변경되었는지 감지하는 스크립트를 만들려고 합니다. 내가 지금까지 가지고 있는 것은 다음과 같습니다.

#!/bin/bash
for FILE in "${PWD}/*"
do
    SUM1="$(md5sum $FILE)"
    sleep 2
    SUM2="$(md5sum $FILE)"
    if [ "$SUM1" = "$SUM2" ];
    then
        echo "Identical"
    else
        echo "Different"
    fi
done

이것은 "동일"값을 한 번만 출력하므로 각 파일을 확인하고 각 파일에 대해 "동일"또는 "다른"을 출력하고 싶습니다.

편집하다: 설치하지 않아도 괜찮나요?inotify-tools팩?

답변1

당신은 그것을 사용할 수 있습니다이노티파이 도구다음과 같이 명령줄에서 확실하게:

inotifywait -r  -m /dir/to/monitor/

~에서사람들은 기다리다

-m,--monitor

단일 이벤트를 수신한 후 종료하는 대신 무기한 실행됩니다. 기본 동작은 첫 번째 이벤트가 발생한 후 종료하는 것입니다.

이것은 man 파일에서 복사된 지속적인 모니터링 스크립트입니다 inotifywait.

#!/bin/sh
while inotifywait -e modify /var/log/messages; do
  if tail -n1 /var/log/messages | grep apache; then
    kdialog --msgbox "Blah blah Apache"
  fi
done

답변2

다른 사람들이 설명했듯이 사용하는 것이 inotify더 나은 솔루션입니다. 스크립트가 실패하는 이유를 설명하겠습니다. 우선, 어떤 언어로 프로그래밍하든 관계없이 무언가를 디버깅하려고 할 때마다 첫 번째 규칙은 "모든 변수 인쇄"입니다.

$ ls
file1  file2  file3
$ echo $PWD    
/home/terdon/foo
$ for FILE in "${PWD}/*"; do echo "$FILE"; done
/home/terdon/foo/*

따라서 위에서 볼 수 있듯이 $FILE실제로는 로 확장됩니다 $PWD/*. 따라서 루프는 한 번만 실행됩니다. /home/terdon/foo/*디렉터리의 각 파일을 개별적으로 대상으로 지정하는 대신. 그러면 md5sum명령은 다음과 같습니다.

md5sum /home/terdon/foo/*

즉, md5sum모든 파일이 아닌 대상 디렉터리의 모든 파일에서 동시에 실행됩니다.

문제는 전역 확장을 참조하여 확장을 방지한다는 것입니다.

$ echo "*"
*
$ echo *
file1 file2 file3

하지만변하기 쉬운거의 똑같아야 하는데항상 인용됨, glob은 이와 같아서는 안 됩니다. 이렇게 하면 glob 대신 문자열이 되기 때문입니다.

당신이하고 싶은 일은 :

for FILE in "${PWD}"/*; do ...

$PWD그러나 여기서 사용할 이유가 없으며 유용한 것을 추가하지 않습니다. 위 줄은 다음과 동일합니다.

for FILE in *; do

또한 쉘 변수에 대문자를 사용하지 마십시오. 이는 시스템 설정을 위한 환경 변수이므로 사용자 고유의 변수를 소문자로 유지하는 것이 가장 좋습니다.

이 모든 것을 고려하여 작동하는 스크립트의 향상된 버전은 다음과 같습니다.

#!/bin/bash
for file in *
do
    sum1="$(md5sum "$file")"
    sleep 2
    sum2="$(md5sum "$file")"
    if [ "$sum1" = "$sum2" ];
    then
        echo "Identical"
    else
        echo "Different"
    fi
done

답변3

inotify-tools패키지를 사용하면 폴더의 모든 변경 사항을 실시간으로 모니터링할 수 있습니다. 예를 들어 다음 inotifywait과 같이 사용할 수 있는 도구가 포함되어 있습니다.

> inotifywait /tmp
Setting up watches.
Watches established.
/tmp/ MODIFY test

플래그를 사용하여 특정 이벤트나 특정 파일만 필터링할 수 있습니다. 이 inotifywatch도구는 파일 시스템 사용 통계를 수집하고 inotify각 이벤트에 대한 개수를 출력합니다.

모니터링을 위해 다른 도구를 사용하려는 경우 매개변수(분 수정) find와 함께 사용할 수 있습니다. -mmin2초는 0.033분과 동일하므로 다음을 사용할 수 있습니다.

find . -type f -mmin 0.033

답변4

#!/bin/bash
# pass one or more folders as arguments
while true; do
  for f in "$@"; do
    date
    echo "Checking $f and subfolders"
    find=$(find "$f" -type f)
    while read -r f2; do
      # strip non-alphanumeric from filename for a variable var name
      v=${f2//[^[:alnum:]]/}
      r=$(md5sum "$f2")
      if [ "$r" = "${!v}" ]; then
        echo "Identical $f2"
      else
        echo "Different $f2"
      fi
      eval "${v}=\$r"
    done <<< "$find"
  done
  sleep 2
done

관련 정보