File Watchers

File system event monitoring for automated rebuilds. inotifywait, entr, watchexec, and development loop patterns.

inotifywait — Filesystem Events

Watch a directory for changes — trigger on modify, create, delete
inotifywait -m -r -e modify,create,delete /path/to/watch/
Continuous rebuild on file change — the development loop
#!/bin/bash
set -euo pipefail

while inotifywait -r -e modify,create --exclude '\.git|build|\.cache' docs/; do
    echo "Change detected, rebuilding..."
    make build
    echo "Build complete"
done

-m (monitor) keeps watching after the first event. -r watches recursively. --exclude takes a regex to skip directories.

Watch specific file types — only trigger on AsciiDoc changes
inotifywait -m -r -e modify --include '\.adoc$' docs/modules/ |
    while IFS= read -r path action file; do
        echo "[$action] $path$file"
        make build
    done

entr — Run Command on File Change

Rebuild when files change — simpler than inotifywait
# Watch all .adoc files, rebuild on change
find docs/ -name '*.adoc' | entr make build

# Clear screen and rebuild
find docs/ -name '*.adoc' | entr -c make build

# Restart a server on change
find src/ -name '*.py' | entr -r python src/server.py

entr reads file paths from stdin. -c clears the screen before each run. -r sends SIGTERM to the child process before restarting.

Watch and rebuild with directory tracking — detect new files
while true; do
    find docs/ -name '*.adoc' | entr -d make build
done

-d causes entr to exit when a new file is added to a watched directory. The outer loop restarts it with the updated file list.

watchexec — Rust-Based File Watcher

Watch and rebuild — with filtering built in
# Watch .adoc files, run make
watchexec -e adoc make build

# Watch multiple extensions
watchexec -e py,yaml,toml pytest

# Exclude directories
watchexec -e adoc --ignore build/ --ignore .cache/ make build
Restart a long-running process on change
watchexec -r -e py -- python src/app.py

-r restarts the process (sends SIGTERM, then starts fresh). Useful for development servers.

Python watchfiles

watchfiles — Python library for file watching
from watchfiles import watch

for changes in watch('docs/'):
    print(f"Changes detected: {changes}")
    # Trigger rebuild
    import subprocess
    subprocess.run(['make', 'build'])
In a FastAPI app — auto-reload is built in
# uvicorn auto-reloads on Python file changes
uvicorn app.main:app --reload --reload-dir src/

fswatch — Cross-Platform

Watch and execute — macOS and Linux
fswatch -o docs/ | xargs -n1 -I{} make build

-o outputs a count of events (not file paths). Each event triggers the piped command.

Practical Patterns

Development server with live rebuild — Antora + watch
#!/bin/bash
set -euo pipefail

# Start server in background
make serve &
server_pid=$!
trap "kill $server_pid 2>/dev/null" EXIT

# Watch for changes and rebuild
while true; do
    find docs/ -name '*.adoc' -o -name '*.yml' | entr -d make build
done
Guard against rapid-fire rebuilds — debounce with sleep
inotifywait -m -r -e modify --include '\.adoc$' docs/ |
    while IFS= read -r path action file; do
        sleep 1  # Debounce: editors write multiple events per save
        make build
    done

Installation

Install file watchers on Arch Linux
# inotify-tools (inotifywait, inotifywatch)
sudo pacman -S inotify-tools

# entr
sudo pacman -S entr

# watchexec
sudo pacman -S watchexec

See Also

  • Make — build targets triggered by file watchers

  • Scripts — wrapper scripts for watch loops