ディレクトリ内のファイルの変更を検出する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

関連情報