inotifywait: Monitorando Eventos do Sistema de Arquivos

inotifywait: Monitorando Eventos do Sistema de Arquivos

O que e inotifywait?

Conclusao: inotifywait usa o recurso inotify do kernel Linux para detectar eventos de criacao/modificacao/exclusao de arquivos sem polling, permitindo disparar automacao no momento em que um arquivo muda.

  • Detectar eventos do sistema de arquivos em tempo real com inotifywait
  • Combinar com um loop while read para construir um padrao de deteccao de mudanca -> processamento automatico
  • Evitar as duas armadilhas: close_write e max_user_watches

Resumo Rapido

  • Esperar uma vez -> inotifywait path
  • Monitorar continuamente e processar eventos -> inotifywait -m -e close_write path
  • Para capturar "salvamento concluido," use close_write, nao modify

Premissas (ambiente)

  • SO: Linux (Ubuntu / Debian / familia RHEL), inotify no kernel 2.6.13+
  • O pacote inotify-tools e necessario (veja abaixo)
  • Sistema de arquivos local assumido (alguns sistemas de arquivos de rede como NFS nao reportam eventos)

Por que usar inotifywait? (vs polling)

Conclusao: Polling com while sleep 1; do ...; done despertica CPU e reage com atraso. inotifywait permite que o kernel envie eventos, entao permanece ocioso com custo baixo e reage instantaneamente.

A forma ingenue de detectar mudancas e executar repetidamente ls ou stat -- polling. Isso tem desvantagens:

  • Um intervalo curto despertica CPU e I/O
  • Um intervalo longo atrasa a deteccao
  • O custo de varredura cresce com o numero de arquivos monitorados

inotifywait registra eventos com o subsistema inotify do kernel e so acorda quando uma mudanca acontece. A carga ociosa e quase zero e a reacao e imediata. Onde o comando watch re-renderiza em um intervalo fixo (polling), inotifywait e orientado a eventos.

Como instalar inotifywait?

Conclusao: inotifywait nao faz parte do coreutils -- vem no pacote inotify-tools. Instale com apt em sistemas baseados em Debian ou dnf em sistemas baseados em RHEL.

# Ubuntu / Debian
$ sudo apt install inotify-tools

# RHEL / Rocky / AlmaLinux (pode precisar de EPEL)
$ sudo dnf install inotify-tools

# Fedora
$ sudo dnf install inotify-tools

Verifique a instalacao:

$ inotifywait --help | head -n 1
inotifywait 3.22.6.0

A ferramenta inclusa inotifywatch agrega estatisticas de eventos ("quais arquivos foram acessados quantas vezes"). Este artigo foca no inotifywait, que transmite eventos um por um para processamento.

Uso basico: monitorando mudancas em arquivos

Conclusao: Passe um caminho e o inotifywait bloqueia ate que um evento ocorra, imprime-o e sai. Adicione -m (monitor) para continuar monitorando continuamente.

Esperar uma vez (one-shot)

$ inotifywait /tmp/watchdir

Toque em um arquivo em /tmp/watchdir a partir de outro terminal e ele imprime um evento, depois sai:

Setting up watches.
Watches established.
/tmp/watchdir/ MODIFY test.txt

A ordem da saida e caminho-monitorado nome-do-evento nome-do-arquivo. Por padrao, monitora todos os tipos de evento e sai no primeiro.

Monitorar continuamente (-m)

Sair toda vez e inutil para automacao. Com -m (--monitor) ele nunca sai e continua emitindo eventos:

$ inotifywait -m /tmp/watchdir
Setting up watches.
Watches established.
/tmp/watchdir/ OPEN test.txt
/tmp/watchdir/ MODIFY test.txt
/tmp/watchdir/ CLOSE_WRITE,CLOSE test.txt

Mensagens de inicializacao como Setting up watches. vao para a saida de erro padrao. Suprima-as com -q (quiet) ao criar scripts.

Quais eventos monitorar? (escolhendo -e)

Conclusao: Use -e para restringir os eventos. Para capturar "salvamento de arquivo concluido," use close_write, nao modify -- modify dispara a cada escrita.

Sem -e (--event), todos os tipos de evento estao no escopo, o que gera muito ruido. Eventos comuns:

Evento Dispara quando
create Um arquivo / diretorio foi criado
modify O conteudo foi escrito (dispara varias vezes)
close_write Um arquivo aberto para escrita foi fechado
delete Um arquivo / diretorio foi excluido
moved_to Um arquivo foi movido / renomeado para este diretorio
moved_from Um arquivo foi movido / renomeado deste diretorio
attrib Permissoes, proprietario ou timestamps mudaram

Especifique varios eventos repetindo -e ou separando-os por virgula.

# Monitorar apenas criacao, conclusao de escrita e exclusao
$ inotifywait -m -e create -e close_write -e delete /tmp/watchdir

Por que close_write ao inves de modify

Editores e programas frequentemente escrevem varias vezes em um unico salvamento, e modify dispara cada vez. Para capturar o momento em que um salvamento termina exatamente uma vez, use close_write, que significa que o arquivo foi fechado. Perca isso e voce tera "o mesmo arquivo processado repetidamente."

Formatando a saida: --format e --timefmt

Conclusao: --format reformata a saida. Os basicos sao %w caminho monitorado, %f nome do arquivo, %e nome do evento, e %T timestamp (usado com --timefmt).

A saida padrao e separada por espacos e dificil de analisar. Use --format para produzir algo amigavel para scripts.

$ inotifywait -m --timefmt '%F %T' --format '%T | %e | %w%f' \
    -e close_write /tmp/watchdir
2026-06-05 21:30:11 | CLOSE_WRITE,CLOSE | /tmp/watchdir/report.csv

Especificadores de formato principais:

  • %w ... o caminho monitorado (o diretorio sendo observado)
  • %f ... o nome do arquivo ao qual o evento se aplica (ao monitorar um diretorio)
  • %e ... os eventos que ocorreram (separados por virgula)
  • %T ... timestamp, formatado pela string strftime de --timefmt

Unir %w%f da o caminho completo. Para mudar o separador, use %Xe, onde X e o caractere separador.

Monitorando diretorios recursivamente (-r e limites de watches)

Conclusao: -r monitora subdiretorios recursivamente, mas cada diretorio consome um watch, e atingir o limite fs.inotify.max_user_watches faz falhar.

$ inotifywait -m -r -e close_write /var/www

Monitorar uma arvore enorme com -r pode produzir este erro:

Failed to watch /var/www; upper limit on inotify watches reached!
Please increase the amount of inotify watches allowed per user via `/proc/sys/fs/inotify/max_user_watches'.

Verifique o limite atual:

$ cat /proc/sys/fs/inotify/max_user_watches
8192

Aumente temporariamente (reseta na reinicializacao):

$ sudo sysctl fs.inotify.max_user_watches=524288

Torne persistente com um arquivo de configuracao:

$ echo 'fs.inotify.max_user_watches=524288' | sudo tee /etc/sysctl.d/90-inotify.conf
$ sudo sysctl --system

Outra ressalva do monitoramento recursivo

O inotify define watches por diretorio. Um subdiretorio profundo criado apos o inicio do monitoramento pode perder eventos durante a breve janela antes de seu watch ser adicionado (uma condicao de corrida). Para arvores onde subdiretorios aparecem frequentemente, projete considerando essa possivel perda.

Pratico: detectar mudancas e processar automaticamente

Conclusao: Canalize inotifywait -m em um loop while read e processe cada arquivo. Passar apenas os valores necessarios via --format mantem a analise estavel.

Processar um CSV toda vez que um e completamente escrito em um diretorio monitorado:

#!/usr/bin/env bash
set -euo pipefail

WATCH_DIR=/var/spool/incoming

inotifywait -m -q \
    --format '%w%f' \
    -e close_write \
    "$WATCH_DIR" |
while read -r filepath; do
    case "$filepath" in
        *.csv)
            echo "Processando: $filepath"
            # Execute o trabalho real aqui (ingestao, transformacao, notificacao, etc.)
            ;;
        *)
            echo "Pulando: $filepath"
            ;;
    esac
done

Pontos principais:

  • -q suprime logs de inicializacao; --format '%w%f' passa apenas o caminho completo
  • Restringir a close_write torna "salvamento concluido" o unico gatilho
  • read -r mantem barras invertidas literais

Prevenir execucoes concorrentes

Se voce lanca este monitor a partir do cron ou systemd, duas instancias podem processar o mesmo arquivo duas vezes. Combine com bloqueio de arquivo com flock para mante-lo em uma unica instancia.

Cuidado com o "salvamento atomico" de editores

Editores como vim podem salvar "escrevendo um arquivo temporario, depois renomeando-o sobre o original." Nesse caso, a mudanca aparece como moved_to ou create, nao close_write. Para capturar salvamentos de editores de forma confiavel, monitore o diretorio para ambos -e close_write -e moved_to.

FAQ do inotifywait

Conclusao: O status de saida e 0 em um evento, 1 em erro e 2 em timeout com -t. Alguns sistemas de arquivos de rede como NFS nao conseguem detectar mudancas feitas por outros hosts.

P. Sair se nenhum evento acontecer dentro de um limite de tempo

Use -t (--timeout) com um numero de segundos. No timeout, o status de saida e 2.

$ inotifywait -t 30 -e close_write /tmp/watchdir

P. Excluir certos caminhos do monitoramento

Passe uma expressao regular estendida para --exclude (sensivel a maiusculas) ou --excludei (insensivel a maiusculas).

$ inotifywait -m -r --exclude '\.git/' -e close_write /repo

P. Pode monitorar arquivos em NFS?

O inotify so reporta mudancas observadas pelo kernel local. Em sistemas de arquivos de rede como NFS, onde outro host escreve os arquivos, essas mudancas podem nao ser detectadas. Considere polling ou outro mecanismo para armazenamento compartilhado.

Proximas Leituras