Как объяснили другие, использование 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
Хотя переменные почти всегда должны заключаться в кавычки , глобусы не должны, поскольку это превращает их в строки, а не в глобусы.
То, что вы хотели сделать, это:
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
for FILE in "${PWD}"/*; do
работает с тем же набором, посколькуfor FILE in *; do
он не совсем эквивалентен, поскольку последний не содержит путей.md5sum -- "$file"
вместоmd5sum "$file"
обработки случай, когда файл начинается с-
. Конечно, вы также должны сделать так, чтобы ваша реализация md5sum поддерживала--
конец разделителя опций.Вы можете использовать inotify-tools определенно из командной строки, например, так:
От человека невинного
А вот скрипт, который непрерывно отслеживает, скопированный из файла man
inotifywait
:источник
Вы можете использовать
inotify-tools
пакет для мониторинга всех изменений в папке в режиме реального времени. Например, он содержитinotifywait
инструмент, который вы можете использовать как:Вы можете использовать флаги для фильтрации только определенных событий или определенных файлов. В
inotifywatch
собирает инструмент файловой системы статистики и выводит отсчеты каждогоinotify
события.Вы можете найти больше примеров здесь, например.
Если вы хотите отслеживать с другими инструментами, вы можете использовать
find
с-mmin
параметром (измененные минуты). Поскольку 2 секунды равны 0,033 минутам, вы можете использовать:источник
Если вы хотите контролировать с интервалом в две секунды, вы можете окружить ваш чек:
Хотя это будет последовательно проверять файлы и будет ждать 2 секунды для каждого найденного файла, я предлагаю преобразовать ваш чек в функцию:
Который можно использовать в
while
цикле:Обратите внимание на
&
амперсанд для выполнения проверок в фоновом режиме для параллельного выполнения проверок файлов. Обратите внимание, что это может повлиять на производительность в зависимости от количества файлов, найденных в каталоге.Также обратите внимание, что я изменил
echo
строки, чтобы включить имя файла ("$@"
), чтобы визуализировать, какой файл найден идентичным / другим.источник
источник