Если я правильно понял вопрос, вам нужно обработать все файлы, которые были созданы или изменены в каталоге с момента последнего запуска вашего скрипта.
По моему мнению, поиск не является правильным инструментом для определенияэти файлы, потому что он не знает, какие файлы он уже видел.
Использование любого из параметров -atime / -ctime / -mtime приведет к дублированию, если вы запустите свой скрипт дважды за указанный период,или пропустите некоторые файлы, если они не были выполнены в нужное время.Сложность синхронизации использования этих опций для чего-то подобного не так проста.
Я могу предложить несколько альтернатив:
a) Использовать три каталога вместо одного: входящий / обработка /сделанный/.Ваши пользователи должны иметь возможность только помещать файлы во входящие /.Вы перемещаете туда любые файлы для обработки / с помощью простого mv incoming/* processing/
перед запуском сценария Perl.Затем вы перемещаете их из обработки / в готовый / когда все закончится.
На мой взгляд, это самое простое и лучшее решение, и оно используется почтовыми серверами и т. Д. При решении этой проблемы.Если бы я был вами, и не было никаких особых обстоятельств, мешающих вам сделать это, я бы прекратил читать здесь.
b) У вашего сценария поиска touch
специальный файл (например, .timestamp
, возможно, вдругой каталог, так что ваши пользователи не будут вмешиваться), когда это будет сделано.Это позволит вашему сценарию запомнить последний раз, когда он был запущен.Затем используйте
find \( -cnewer .timestamp -o -newer .timestamp \) -type f -exec ./script.pl '{}' ';'
, чтобы запустить скрипт perl для каждого файла.Вы должны изменить свой Perl-скрипт, чтобы он мог запускаться повторно с разными именами файлов каждый раз.Если вы можете изменить его так, чтобы он принимал несколько файлов за один раз, вы также можете запустить его с
find \( -cnewer .timestamp -o -newer .timestamp \) -type f -exec ./script.pl '{}' +
, что сведет к минимуму количество процессов ./script.pl.Будьте внимательны при первом запуске сценария поиска, когда отсутствует файл .timestamp.Хорошим решением было бы просто проигнорировать это, не используя - * более новые опции в этом случае.Также имейте в виду, что существует условие состязания, когда файлы, добавленные после запуска поиска, но до прикосновения к метке времени, не будут обрабатываться.
c) В качестве варианта (b) ваш скрипт должен обновить метку временисо временем обработанного файла, который был создан / изменен совсем недавно.Это сложно, потому что find
не может самостоятельно упорядочить вывод.Вы можете использовать обертку вокруг вашего Perl-скрипта для обработки этого:
#!/bin/bash
for i in "$@"; do
find "$i" \( -cnewer .timestamp -o -newer .timestamp \) -exec touch -r '{}' .timestamp ';'
done
./script.pl "$@"
Это обновит временную метку, если она вызывается для обработки файла с более новым mtime или ctime, минимизируя (но не устраняя) гонкусостояние.Однако это несколько неловко - неизбежно, так как опция bash [[-nt, кажется, только проверяет mtime.Возможно, было бы лучше, если бы ваш скрипт perl обрабатывал это сам по себе.
d) Пусть ваш скрипт хранит где-нибудь каждое обработанное имя файла и его временные метки, а затем пропускает дубликаты.Это позволило бы вам просто передать все файлы в каталоге и позволить ему разобраться в беспорядке.Довольно сложно, хотя ...
e) Поскольку вы используете Linux, вы можете взглянуть на inotify и пакет инструментов inotify - в частности, инструмент inotifywait.С небольшим количеством сценариев это позволит вам обрабатывать файлы по мере их добавления в каталог:
inotifywait -e MOVED_TO -e CLOSE_WRITE -m -r testd/ | grep --line-buffered -e MOVED_TO -e CLOSE_WRITE | while read d e f; do ./script.pl "$f"; done
Это не имеет условий гонки, если ваши пользователи не создают / копируют / перемещают любые каталоги , а не только файлы.