Configs2026年4月14日·1 分钟阅读

watchexec — Run Commands When Files Change, with Smart Defaults

watchexec watches a directory tree and runs a command when anything changes. Cross-platform, respects .gitignore, debounces, restarts long-running processes — the swiss-army knife of file-watching.

Introduction

watchexec is the "watch these files, run this command" tool for everyone who's ever hacked together the same bash script with inotifywait or fswatch. Written in Rust, it works identically on macOS, Linux, and Windows, respects .gitignore by default, debounces rapid saves, and can restart processes on change (sending proper SIGTERM then SIGKILL).

With over 7,000 GitHub stars, watchexec powers many developer tools' "watch mode" under the hood (including cargo-watch built directly on top of it). If you've ever wanted a reliable file-watcher, this is the one.

What watchexec Does

watchexec monitors directory trees with native filesystem events (FSEvents on macOS, inotify on Linux, ReadDirectoryChangesW on Windows). When events arrive, it debounces them (coalesce bursts), applies include/exclude filters, and runs a shell command or replaces the running process.

Architecture Overview

[Filesystem]
     |
[Native watcher: FSEvents / inotify / ReadDirectoryChangesW]
     |
[Event Stream]
   batched + debounced (100ms default)
     |
[Filter Layer]
   --exts / --filter-file / .gitignore / --ignore
     |
[Exec Layer]
   run command, or restart (-r)
   signal: SIGTERM -> SIGKILL after grace period
   clear screen (-c), emit bell (-N), notify (-n)

Self-Hosting & Configuration

# Debounce changes over 500ms, ignore node_modules
watchexec --debounce 500 -i node_modules -- npm run build

# Multiple commands on change (shell)
watchexec -- "npm run lint && npm test"

# Restart a server, send SIGINT instead of SIGTERM
watchexec -r --signal SIGINT -- node server.js

# Watch only Go files, clear screen, send bell on run
watchexec -e go -c -N -- go test ./...

# Run once immediately then wait for changes
watchexec --on-busy-update=restart -w . --project-origin . -- ./dev.sh

# Using an environment file to pass changed file names
watchexec --emit-events-to=environment -- bash -c 'echo "$WATCHEXEC_WRITTEN_PATH changed"'
# Common language-specific workflows
watchexec -e py -- pytest
watchexec -e go -- go test ./...
watchexec -e rs -- cargo test
watchexec -e ts,tsx -- bun run build
watchexec -e md -- mdbook build

# With pre-commit-style hooks
watchexec -e py -- "ruff check . && pytest -q"

Key Features

  • Cross-platform — same flags work on macOS, Linux, Windows
  • .gitignore aware — skip ignored files by default
  • Debouncing — coalesce bursts of saves into one run
  • Process restart-r kills and restarts long-running servers cleanly
  • Extension filters-e go,mod,sum common shorthand
  • Clear / bell / notify — UX niceties built-in
  • Event metadata — pass changed paths to the command via env vars
  • Library + CLI — Rust library used by cargo-watch, lefthook, and others

Comparison with Similar Tools

Feature watchexec entr fswatch inotifywait nodemon
Language Rust C C++ C Node
Cross-platform Yes Unix Unix + partial Win Linux only Yes
Debouncing Built-in Manual Manual Manual Built-in
.gitignore Built-in Manual Manual Manual Built-in
Restart on change Yes (-r) Manual Manual Manual Yes (focus)
Best For Universal watcher Unix hackers Bash + fsevents Linux-only workflows Node-specific

FAQ

Q: watchexec vs entr? A: watchexec is cross-platform, .gitignore-aware, debounced by default. entr is simpler (just reads file list from stdin) but Unix-only. watchexec is more robust for cross-platform dev teams.

Q: Does it stop on errors? A: By default no — it keeps waiting for the next change. Combine with shell: watchexec -- "cmd || true" to suppress failure, or use --on-busy-update=signal for more control.

Q: Can I pass the changed file name to my command? A: Yes — --emit-events-to=environment sets WATCHEXEC_WRITTEN_PATH, WATCHEXEC_CREATED_PATH, etc., in the command's env. Or --emit-events-to=stdio to pipe events as JSON.

Q: Does it work over network filesystems? A: Partially. NFS and SMB may miss events (they depend on the filesystem driver). For critical workflows, watch a local mount or poll with --poll=200ms.

Sources

讨论

登录后参与讨论。
还没有评论,来写第一条吧。

相关资产