ディレクトリ内のファイルが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
で使用できます。-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