Используя inotifywait, можно отслеживать только новые файлы.
Я бы попросил дать определение "нового файла". man inotifywait определяет список событий, в котором также перечислены события, такие как create
и delete
и delete_self
, а inotifywait также может просматривать «старые файлы» (определяемые как файлы, существующие до выполнения inotifywait) и каталоги.Вы указали только одно событие -e modify
, которое уведомляет об изменении файлов в $ {path}, оно включает в себя изменение как ранее существующих файлов, так и созданных после inotify выполнения.
.... как можно убедиться, что скрипт будет перехватывать все файлы?
Твоего скрипта достаточно, чтобы перехватить все события, которые происходят внутри пути.Если у вас нет средств синхронизации между частью, которая генерирует файлы, и частью, которая получает, вы ничего не можете сделать, и всегда будет состоянием гонки.Что если ваш сценарий получит 0% процессорного времени, а часть, которая генерирует файлы, получит 100% процессорного времени?Нет никакой гарантии, что процессорное время будет между процессами (если только не используется сертифицированная система реального времени ...).Реализуйте синхронизацию между ними.
Вы можете посмотреть другое событие.Если генерирующие сайты закрывают файлы, когда готовы с ними, следить за событием закрытия.Также вы можете запустить work on/with NEWFILE
параллельно в фоновом режиме, чтобы ускорить выполнение и чтение новых файлов.Но если принимающая сторона медленнее, чем отправляющая, если ваш скрипт работает с NEWFILE медленнее, чем генерирующая часть новых файлов, вы ничего не можете сделать ...
Если у вас нет специальных символов и пробелов вимена файлов, я бы сказал:
inotifywait -m -e modify "${path}" |
while IFS=' ' read -r path event file ;do
lock "${path}"
work on "${path}/${file}"
ex. mv "${path}/${file}" ${new_location}
unlock "${path}"
done
, где lock
и unlock
- это некоторые механизмы блокировки, реализованные между вашим сценарием и генерирующей частью.Вы можете создать связь между процессом создания файлов и процессом обработки файлов.
Я думаю, что вы можете использовать некоторую файловую систему транзакций, которая позволит вам "заблокируйте каталог из других сценариев, пока вы не будете готовы к работе над ним, но у меня нет опыта в этой области.
Я попытался объединить два цикла.Но если файлы приходят быстро и в больших количествах, происходит изменение в том, что файлы будут поступать, когда будет запущен второй цикл.
Запустите process_new_file_loop в фоновом режиме перед запуском process_old_files_loop.Также было бы неплохо убедиться (т.е. синхронизировать), что inotifywait успешно запущен, прежде чем вы продолжите цикл обработки существующих файлов, чтобы между ними также не было условий гонки.
Может быть, простоПример и / или начальная точка могут быть:
work() {
local file="$1"
some work "$file"
mv "$file" "$predefiend_path"
}
process_new_files_loop() {
# let's work on modified files in parallel, so that it is faster
trap 'wait' INT
inotifywait -m -e modify "${path}" |
while IFS=' ' read -r path event file ;do
work "${path}/${file}" &
done
}
process_old_files_loop() {
# maybe we should parse in parallel here too?
# maybe export -f work; find "${path} -type f | xargs -P0 -n1 -- bash -c 'work $1' -- ?
find "${path}" -type f |
while IFS= read -r file; do
work "${file}"
done
}
process_new_files_loop &
child=$!
sleep 1
if ! ps -p "$child" >/dev/null 2>&1; then
echo "ERROR running processing-new-file-loop" >&2
exit 1
fi
process_old_files_loop
wait # wait for process_new_file_loop
Если вы действительно заботитесь о скорости выполнения и хотите сделать это быстрее, перейдите на python или на C (или на что угодно, кроме shell).Bash не быстрый, это оболочка, он должен использоваться для соединения двух процессов (передачи стандартного вывода одного в стандартный поток другого), а синтаксический анализ строки потока за строкой while IFS= read -r line
чрезвычайно медленный в bash и обычно должен использоваться как последнийкурорт.Возможно, использование xargs
, как xargs -P0 -n1 sh -c "work on $1; mv $1 $path" --
или parallel
, будет означать ускорение, но средняя программа на Python или C, вероятно, будет в n-й раз быстрее.