디렉터리에서 파일의 변경 사항을 감지하는 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

당신이 사용할 수있는inotify 도구확실히 명령줄에서, 예를 들면 다음과 같습니다:

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

에서남자 inotify기다려

-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대상 디렉터리의 모든 파일에서 동시에 실행되며 각 파일에서 실행되지는 않습니다.

문제는 glob 확장을 인용하여 확장이 중단된다는 것입니다.

$ 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됩니다 -mmin. 2초는 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

관련 정보