entr
Run commands when files change
TLDR
Rebuild with make if any file in any subdirectory changes
Rebuild and test with make if any .c source files in the current directory change
Send a SIGTERM to any previously spawned ruby subprocesses before executing ruby main.rb
Run a command with the changed file (/_) as an argument
[c]lear the screen and run a query after the SQL script is updated
Rebuild the project if source files change, limiting output to the first few lines
Launch and auto-[r]eload a Node.js server
SYNOPSIS
entr [options] command ...
Example:
find . -name "*.go" | entr -r go run .
This command finds all .go files and pipes them to entr. entr then reloads itself (-r) and runs 'go run .' whenever any of these .go files change.
PARAMETERS
-c
Clear the screen before executing the command.
-d
Watch directories for new files. By default, entr only monitors existing files for changes.
-p
Build a fresh list of files before each execution. Useful when files are frequently added or removed from the monitored set.
-r
Reload entr itself when a watched file changes, effectively re-reading its standard input. This is crucial when the list of monitored files can change, e.g., if a Makefile is modified.
-s
Suppress entr's own output messages, only showing the executed command's output. Useful for cleaner terminal output.
-n
Start the command immediately upon launch, then re-run it on subsequent file changes. The default behavior (without -n) is to wait for the first change before execution.
-a utility
Instead of reading the file list from standard input, execute the specified utility to generate the list of files to monitor. For example: entr -a 'git ls-files' go test ./...
-t timeout
Terminate the running command if it does not complete within timeout seconds.
-v
Produce verbose output from entr itself, showing more details about internal operations.
DESCRIPTION
entr is a command-line utility that automatically executes a specified command whenever monitored files are modified. It's an invaluable tool for developers, enabling automated tasks like recompiling code, running tests, or refreshing a server immediately after source files are saved. It reads the list of files to monitor from standard input, making it highly flexible and often used in conjunction with other commands like find or git ls-files. This allows users to precisely define which files or directories trigger command execution, streamlining development workflows by eliminating the need for manual re-execution of tasks.
CAVEATS
entr typically relies on kernel-level file system event notification mechanisms (like inotify on Linux), which have limits on the total number of files or directories that can be watched. Exceeding these limits can lead to errors or missed events.
Monitoring a very large number of files or deeply nested directories can consume significant system resources.
The command executed by entr is run in a new shell environment.
Changes are detected based on file modification times (mtime) and size, not content hashes, which is efficient but might miss some rare, specific types of 'changes' that don't alter these attributes.
TYPICAL USAGE PATTERN
The most common way to use entr is by piping a list of files to its standard input.
Example for monitoring all .js files and running a linter:
find . -name "*.js" | entr eslint .
Example for recompiling Go code when any .go file changes:
ls *.go | entr -r go build -v .
The -r option is particularly important when the list of files to be monitored can change, as it causes entr to re-read its input.
SIGNAL HANDLING
entr gracefully forwards signals (like SIGINT when you press Ctrl+C) to the currently running command. This allows you to stop the executed command and then entr itself with a single Ctrl+C press. If the command takes a long time to shut down, you might need to press Ctrl+C multiple times.
HISTORY
entr was created by Erik Kastner as a lightweight, efficient, and simple tool for running commands on file changes. Its development was driven by the need for a focused utility that could seamlessly integrate into Unix-like command-line pipelines. Being written in C, it offers high performance and minimal overhead, which contributed to its growing popularity in development and automation workflows as a more robust alternative to simple command loops or more complex build systems.
SEE ALSO
find(1), xargs(1), inotifywait(1), watchexec, nodemon, fswatch