Você pode usar uma das ferramentas de pesquisa que pré-datam dnotify e inotify : gamin ou fam , juntamente com algo como fileschanged que é uma ferramenta inotifywait
-like da CLI. Os projetos gamin e fam estão relacionados, e ambos são bem antigos (apesar de serem um pouco menos).
Para tarefas simples e portáteis, usei algo assim via cron:
if mkdir /var/lock/mylock; then
( cd /mnt/mypath; find . -type f -mmin +2 ) | myprocess
rmdir /var/lock/mylock
else
logger -p local0.notice "mylock found, skipping run"
fi
Isso usa bloqueio primitivo e um condicional GNU find
para encontrar apenas arquivos antigos de dois minutos para que eu possa ter certeza de que os arquivos foram gravados completamente. No meu caso myprocess
era rsync --remove-source-files --files-from=-
, então os arquivos foram removidos depois de processados.
Essa abordagem também permite usar find -print0
/ xargs -0
/ rsync -0
para lidar com nomes de arquivos problemáticos.
Se você precisar manter todos os arquivos (antigos e novos) na mesma hierarquia de diretórios, a criação de instantâneos de listagem de diretórios e a distribuição deles também funcionarão para você:
if mkdir /var/lock/mylock; then
(
export LC_COLLATE=C # for sort
cd /mnt/mypath
find . -type f -a \! -name ".dirlist.*" -printf '%pif mkdir /var/lock/mylock; then
( cd /mnt/mypath; find . -type f -mmin +2 ) | myprocess
rmdir /var/lock/mylock
else
logger -p local0.notice "mylock found, skipping run"
fi
' |
while read -d '' file; do
printf "%q\n" "${file}"
done > .dirlist.new
[[ -f .dirlist.old ]] && {
comm -13 <(sort .dirlist.old) <(sort .dirlist.new) |
while read -r file; do
myprocess "${file}"
done
}
mv .dirlist.new .dirlist.new
)
rmdir /var/lock/mylock
else
logger -p local0.notice "mylock found, skipping run"
fi
Este script bash
:
- usa
find -printf
para imprimir uma lista de arquivos delimitados por \ 0 (nul) - usa
read -d ''
para processar essa lista eprintf %q
para escapar nomes de arquivos quando necessário - compara os arquivos .dirlist novos e anteriores
- invoca
myprocess
com cada novo arquivo (citado com segurança)
(Também lidar com arquivos modificados exigiria um pouco mais de esforço, um formato de linha dupla com find ... -printf '%p
poderia ser usado, com alterações associadas aos %code% loops.) while
%s %Ts%code%'