Por que o inotifywatch não detecta alterações nos arquivos adicionados?

14

Estou tentando monitorar /tmpalterações na minha pasta usando inotifywatch:

sudo inotifywatch -v -r /tmp

Depois de criar alguns arquivos ( touch /tmp/test-1 /tmp/test-2), estou terminando inotifywatch(por Ctrl- o Cque me mostra as seguintes estatísticas:

Establishing watches...
Setting up watch(es) on /tmp
OK, /tmp is now being watched.
Total of 39 watches.
Finished establishing watches, now collecting statistics.
total  attrib  close_write  open  create  filename
8      2       2            2     2       /tmp/

A saída imprime apenas as estatísticas, mas não os arquivos que eu esperava (como aqui ou aqui ). Eu tentei diferentes tipos de acesso (via cat, mktempetc.), mas é a mesma coisa.

Perdi algo? É porque eu estou no VPS e algo foi restringido?

SO: Debian 7.3 (inotify-tools) em VPS

kenorb
fonte

Respostas:

14

Isso se deve à maneira como você está usando inotifywatche à maneira como a própria ferramenta funciona. Quando você executa inotifywatch -r /tmp, você começa a assistir /tmpe todos os arquivos que estão nele. Quando você cria um arquivo dentro /tmp, os metadados do diretório são atualizados para conter o número do inode do novo arquivo, o que significa que a alteração ocorre /tmp, não /tmp/test-1. Além disso, como /tmp/test-1não estava lá quando inotifywatchiniciado, não há inotifyrelógio colocado nele. Isso significa que qualquer evento que ocorra em um arquivo criado após a colocação dos relógios não será detectado . Você pode entender melhor se você mesmo:

$ inotifywatch -rv /tmp &
Total of n watches.
$ cat /sys/kernel/debug/tracing/trace | grep inotifywatch | wc -l
n

Se você ativou o mecanismo de rastreamentoinotify_add_watch(2) , o último comando fornecerá o número de relógios configurados por inotifywatch. Esse número deve ser o mesmo que o dado por inotifywatchsi só. Agora, crie um arquivo dentro /tmpe verifique novamente:

$ inotifywatch -rv /tmp &
Total of n watches.
$ touch /tmp/test1.txt
$ cat /sys/kernel/debug/tracing/trace | grep inotifywatch | wc -l
n

O número não aumentou, o que significa que o novo arquivo não é assistido. Observe que o comportamento é diferente se você criar um diretório:

$ inotifywatch -rv /tmp &
Total of n watches.
$ mkdir /tmp/test1
$ cat /sys/kernel/debug/tracing/trace | grep inotifywatch | wc -l
n + 1

Isso se deve à maneira como o -rswitch se comporta :

-r, --recursive: [...] Se novos diretórios forem criados nos diretórios monitorados, eles serão monitorados automaticamente.

Edit: Eu tenho um pouco confuso entre os dois exemplos, mas no primeiro caso , os relógios estão correctamente colocados porque as chamadas de usuários inotifywatchem ~/*(que é expandido, ver o comentário de don_crissti aqui ). O diretório inicial também é monitorado porque ~/.*contém ~/.. Teoricamente, ele também deve conter o ~/..que, combinado com a -rchave, deve resultar na observação de todo o sistema.

No entanto, é possível obter o nome do arquivo acionando um evento de criação em um diretório monitorado, mas acho inotifywatchque não recupera essas informações (elas são salvas um pouco mais profundas que o nome do diretório). inotify-toolsfornece outra ferramenta, chamada inotifywait, que pode se comportar de maneira semelhante inotify-watch, e fornece mais opções de saída (incluindo o %fque você está procurando aqui):

inotifywait -m --format "%e %f" /tmp

Na página do manual :

--format <fmt>Saída em um formato especificado pelo usuário, usando a sintaxe do tipo printf. [...] As seguintes conversões são suportadas:

%f: quando um evento ocorrer em um diretório, ele será substituído pelo nome do arquivo que causou a ocorrência do evento .

%e: substituído pelo (s) evento (s) que ocorreram, separados por vírgula.

Além disso, a -mopção (monitor) continuará inotifywaitsendo executada após o primeiro evento, o que reproduzirá um comportamento bastante semelhante ao inotifywatch.

John WH Smith
fonte
1
.bashrcno exemplo @ serverfaultnão aparece nas estatísticas porque o usuário monitora seu diretório inicial recursivamente, mas porque path/.*é expandido e, como resultado, um monitoramento é definido para todos os arquivos em path/( .bashrcincluído). O comando usado pelo OP nunca produzirá nomes de arquivos porque os relógios estão definidos /tmpe quaisquer subdiretórios, portanto, as estatísticas pertencem apenas a /tmpseus subdiretórios (por exemplo, você verá que os arquivos foram acessados ​​/ movidos / etc), mas não informará seus nomes).
31814 Don_crissti
@don_crissti Ops, eu misturei os dois exemplos dados pelo OP. Eu editei minha resposta, obrigado!
John WH Smith
Obrigado, foi útil. Aqui é o meu comando para mostrar o conteúdo de todos os arquivos de teste * recém-criadas em /tmp: inotifywait -m --format "%f" /tmp | grep --line-buffered ^test | xargs -L1 -I% sudo cat /tmp/% 2> /dev/null.
Kenorb
Além disso: " Isso significa que qualquer evento que ocorra em um arquivo criado após a colocação dos relógios não será detectado. " refletido nas estatísticas desse diretório específico. Veja a inotifywatchsaída na pergunta OP: os 2 createeventos estão lá (portanto, são detectados), mas como inotifywatchobserva um diretório (+ quaisquer subdiretórios), as estatísticas pertencem apenas a esses / esses diretórios.
31124 don_crissti
1
Eu não acho que estamos no mesmo comprimento de onda aqui ... man inotify: When a directory is monitored, inotify will return events for the directory itself, and for files inside the directory.Além disso, man inotifywatché claro sobre quais eventos estão sendo observados: EVENTS>> ... Um arquivo monitorado ou em um diretório monitorado foi acessado / fechado / aberto / etc (significa incluir eventos "que ocorrem em um arquivo" ). Os eventos para um arquivo criado após definir a inspeção no diretório pai SERÃO detectados e refletidos nas inotifywatchestatísticas (NÃO mencionará para quais arquivos esses eventos ocorreram).
31414