inotifywait: Monitorando Eventos do Sistema de Arquivos

inotifywait: Monitorando Eventos do Sistema de Arquivos

O que é inotifywait?

Conclusão: inotifywait usa o recurso inotify do kernel Linux para detectar eventos de criação/modificação/exclusão de arquivos sem polling, permitindo disparar automação 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 padrão de detecção de mudança -> processamento automático
  • Evitar as duas armadilhas: close_write e max_user_watches

Resumo Rápido

  • Esperar uma vez -> inotifywait path
  • Monitorar continuamente e processar eventos -> inotifywait -m -e close_write path
  • Para capturar "salvamento concluído," use close_write, não modify

Premissas (ambiente)

  • SO: Linux (Ubuntu / Debian / família RHEL), inotify no kernel 2.6.13+
  • O pacote inotify-tools é necessário (veja abaixo)
  • Sistema de arquivos local assumido (alguns sistemas de arquivos de rede como NFS não reportam eventos)

Por que usar inotifywait? (vs polling)

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

A forma ingenue de detectar mudanças é executar repetidamente ls ou stat -- polling. Isso tem desvantagens:

  • Um intervalo curto despertica CPU e I/O
  • Um intervalo longo atrasa a detecção
  • O custo de varredura cresce com o número de arquivos monitorados

inotifywait registra eventos com o subsistema inotify do kernel e só acorda quando uma mudança acontece. A carga ociosa é quase zero e a reação é imediata. Onde o comando watch re-renderiza em um intervalo fixo (polling), inotifywait é orientado a eventos.

Como instalar inotifywait?

Conclusão: inotifywait não 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 instalação:

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

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

Uso básico: monitorando mudanças em arquivos

Conclusão: Passe um caminho e o inotifywait bloqueia até 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 saída é caminho-monitorado nome-do-evento nome-do-arquivo. Por padrão, monitora todos os tipos de evento e sai no primeiro.

Monitorar continuamente (-m)

Sair toda vez é inútil para automação. 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 inicialização como Setting up watches. vão para a saída de erro padrão. Suprima-as com -q (quiet) ao criar scripts.

Quais eventos monitorar? (escolhendo -e)

Conclusão: Use -e para restringir os eventos. Para capturar "salvamento de arquivo concluído," use close_write, não modify -- modify dispara a cada escrita.

Sem -e (--event), todos os tipos de evento estão no escopo, o que gera muito ruído. Eventos comuns:

Evento Dispara quando
create Um arquivo / diretório foi criado
modify O conteúdo foi escrito (dispara várias vezes)
close_write Um arquivo aberto para escrita foi fechado
delete Um arquivo / diretório foi excluído
moved_to Um arquivo foi movido / renomeado para este diretório
moved_from Um arquivo foi movido / renomeado deste diretório
attrib Permissões, proprietário ou timestamps mudaram

Especifique vários eventos repetindo -e ou separando-os por vírgula.

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

Por que close_write ao invés de modify

Editores e programas frequentemente escrevem várias vezes em um único 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 você terá "o mesmo arquivo processado repetidamente."

Formatando a saída: --format e --timefmt

Conclusão: --format reformata a saída. Os básicos são %w caminho monitorado, %f nome do arquivo, %e nome do evento, e %T timestamp (usado com --timefmt).

A saída padrão é separada por espaços e difícil de analisar. Use --format para produzir algo amigável 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 diretório sendo observado)
  • %f ... o nome do arquivo ao qual o evento se aplica (ao monitorar um diretório)
  • %e ... os eventos que ocorreram (separados por vírgula)
  • %T ... timestamp, formatado pela string strftime de --timefmt

Unir %w%f dá o caminho completo. Para mudar o separador, use %Xe, onde X é o caractere separador.

Monitorando diretórios recursivamente (-r e limites de watches)

Conclusão: -r monitora subdiretórios recursivamente, mas cada diretório consome um watch, e atingir o limite fs.inotify.max_user_watches faz falhar.

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

Monitorar uma árvore 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 reinicialização):

$ sudo sysctl fs.inotify.max_user_watches=524288

Torne persistente com um arquivo de configuração:

$ 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 diretório. Um subdiretório profundo criado após o início do monitoramento pode perder eventos durante a breve janela antes de seu watch ser adicionado (uma condição de corrida). Para árvores onde subdiretórios aparecem frequentemente, projete considerando essa possível perda.

Prático: detectar mudanças e processar automaticamente

Conclusão: Canalize inotifywait -m em um loop while read e processe cada arquivo. Passar apenas os valores necessários via --format mantém a análise estável.

Processar um CSV toda vez que um é completamente escrito em um diretório 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 inicialização; --format '%w%f' passa apenas o caminho completo
  • Restringir a close_write torna "salvamento concluído" o único gatilho
  • read -r mantém barras invertidas literais

Prevenir execuções concorrentes

Se você lanca este monitor a partir do cron ou systemd, duas instâncias podem processar o mesmo arquivo duas vezes. Combine com bloqueio de arquivo com flock para mantê-lo em uma única instância.

Cuidado com o "salvamento atômico" de editores

Editores como vim podem salvar "escrevendo um arquivo temporário, depois renomeando-o sobre o original." Nesse caso, a mudança aparece como moved_to ou create, não close_write. Para capturar salvamentos de editores de forma confiável, monitore o diretório para ambos -e close_write -e moved_to.

FAQ do inotifywait

Conclusão: O status de saída e 0 em um evento, 1 em erro e 2 em timeout com -t. Alguns sistemas de arquivos de rede como NFS não conseguem detectar mudanças feitas por outros hosts.

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

Use -t (--timeout) com um número de segundos. No timeout, o status de saída é 2.

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

P. Excluir certos caminhos do monitoramento

Passe uma expressão regular estendida para --exclude (sensível a maiúsculas) ou --excludei (insensível a maiúsculas).

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

P. Pode monitorar arquivos em NFS?

O inotify só reporta mudanças observadas pelo kernel local. Em sistemas de arquivos de rede como NFS, onde outro host escreve os arquivos, essas mudanças podem não ser detectadas. Considere polling ou outro mecanismo para armazenamento compartilhado.

Próximas Leituras