Inotifywait para um grande número de arquivos em um diretório

7

O que eu quero fazer é monitorar um diretório (não recursivo, apenas um) para novos arquivos criados e anexar esses arquivos a um único arquivo grande enquanto eles estão sendo escritos.

O número de arquivos que estão sendo gravados é enorme, podendo chegar a até 50.000.

Usando inotifywait , estou monitorando o diretório como:

inotifywait -m -e create ~/folder | awk '($2=="CREATE"){print $3}' > ~/output.file

Portanto, estou armazenando nomes de novos arquivos criados em ~/output.file e, em seguida, usando um loop for

for FILE in 'cat ~/output.file' 
do
    cat $FILE >> ~/test.out
done

Funciona bem, se a taxa na qual um arquivo está sendo gravado (criado) em ~/folder for igual a 1 arquivo por segundo.

Mas o requisito é grande e a taxa na qual os arquivos estão sendo criados é muito alta, como 500 arquivos por minuto (ou até mais).

Eu verifiquei o número de arquivos no ~/folder depois que o processo foi concluído, mas ele não corresponde à saída inotifywait . Há uma diferença de 10 a 15 arquivos, varia.

Além disso, o loop

for FILE in 'cat ~/output.file'
do
done

não processa todos os arquivos em ~/output.file enquanto eles estão sendo gravados.

Alguém por favor pode me sugerir uma solução elegante para esse problema?

    
por rohitkulky 26.05.2013 / 12:14

2 respostas

6

Existe algum motivo específico para você estar usando:

 | awk '($2=="CREATE"){print $3}' > ~/output.file

em vez de inotifywait opções como --format e --outfile ?

Se eu correr:

inotifywait -m --format '%f' -e create /home/don/folder/ --outfile /home/don/output.file

abra outra guia, cd to ~/folder e execute:

time seq -w 00001 50000 | parallel touch {}

real    1m44.841s
user    3m22.042s
sys     1m34.001s

(para obter mais de 500 arquivos por minuto) tudo funciona bem e output.file contém todos os nomes dos arquivos 50000 que acabei de criar.
Quando o processo terminar de gravar os arquivos no disco, você pode anexá-los ao seu test.out (supondo que você esteja sempre em ~/folder ):

xargs < /home/don/output.file cat >> final.file

Ou use read se você quiser processar os arquivos à medida que eles são criados. Então, while em ~/folder você pode executar:

inotifywait -m --format '%f' -e create ~/folder | while read file; do cat -- "$file" >> ~/test.out; done

Observe que, em inotifywait stable, -m e -t não podem ser usados juntos. Suporte para o uso de as duas opções foram adicionadas recentemente, por isso, se você criar inotify-tools de git você deve ser capaz de usar monitor com timeout (para especificar quanto tempo tem que esperar por um evento a ocorrer antes de sair). Eu testei a versão git no meu sistema (saia se nenhum evento create ocorrer em 2 segundos) e ele funciona bem:

inotifywait -m -t 2 --format '%f' -e create ~/folder | while read file; do cat -- "$file" >> ~/test.out; done
    
por 26.05.2013 / 18:11
0

Uma coisa que você pode fazer é criar um pequeno programa que mova os arquivos processados para fora do diretório para outro depois que eles forem processados. Apenas reinicie a verificação do diretório depois de terminar. Durma por um período de tempo razoável antes de redigitalizar se não houver arquivos e faça isso durante a geração de arquivos (o processo que gera os arquivos parece estar em execução por até 100 minutos).

Se você não puder mover os arquivos do diretório, outra abordagem é começar com um DTS de data e hora em algum lugar no passado. Em seguida, localize todos os arquivos mais recentes que o DTS, processe-os e atualize o DTS se o registro de data e hora do arquivo for mais recente que o DTS. Repita este processo como na solução acima. Se a granularidade de seus timestamps impedir que dois arquivos tenham o mesmo, você poderá procurar por arquivos mais recentes que o DTS. Se não, você tem que procurar arquivos não mais antigos que o DTS e manter uma lista de arquivos com o DTS que você vai usar na próxima execução e filtrá-los na próxima execução.

    
por 26.05.2013 / 13:22