overview | download 4.4 | man page
Rebuild project if sources change
$ ls | entr make
Rebuild project and run tests if the build was successful
$ ls | entr -s 'make && make test'
ls(1)in that they recognize files by their contents and are smart enough to skip directories such as
The Event Notify Test Runner is a general purpose Unix utility intended to make rapid feedback and automated testing natural and completely ordinary.
Some graphical applications such as the PostScript/PDF viewer
ship with a
option with reloads the document whenever the source file is modified.
This is useful, but it is even better for applications to provide a
programmatic means of refreshing the display. The browser add-on
has attempted to solve this problem for web developers by injecting
complex, indeed this is all that is required:
$ ls *.css *.html | entr reload-browser Firefox
is a simple script which uses
or AppleScript to send a refresh keystroke to the active tab in your
browser. Some lesser known browsers, such as
can be controlled from the command line using arguments
It is not uncommon for modern web frameworks to continuously hunt for file system changes and auto-reloads when run in single threaded or standalone mode. This functionality is superfluous if the application can respond to signals. The following will instruct mupdf to reload a PDF whenever it is updated:
$ ls *.pdf | entr pkill -HUP mupdf
is a zero-configuration tool with no external
build or runtime dependencies. The interface to
is not only minimal, it aims to be simple enough to create a new category
of ad hoc automation. These
reduce keystrokes, but more importantly they emphasize the utility of
Tightening the edit-test feedback loop requires a tool that is tuned for one task. inotifywait is lightweight, but it only works on Linux, and does not provide a direct means of saying “run this command if any of these files change”. In practice scripting with inotify-tools is difficult because there are a number of significant conditions to contend with:
entrdeals with this by closing the old file descriptor and reopening it using the same pathname. Since there is a small delay while the new file is renamed, we must wait for the new file to appear before running the supplied command and attempting to watch the new file.
entrallows you to safely edit files while tests are running without a repeated invocation of the utility.
entrrepeatedly probes for subsequent events, and only executes the utility when the kernel returns with no results after a short timeout.
IN_MODIFY|IN_CLOSE_WRITEand on BSD kqueue may report
entrretries the execution.
entrconsolidates events over 50ms before responding.
backupoption is set. To deal with this events must be explicitly unregistered to prevent the kernel from tracking changes to backup files.
adheres to the principle of separation
of concerns, yet the reload
option was added to solve a common use case that would otherwise require
some careful scripting:
$ ls *.rb | entr -r ruby main.rb
The 3.1 release further tuned this behavior by setting a process group to ensure that all child processes receive a signal. This enables you to use a startup script without having to write custom signal in handlers.
Other special-purpose flags were added because they reduce highly
repetitive actions or reduce friction. One of the most repetitive actions
was to clear the screen before running tests; hence the
$ ls -d * | entr -c ./test.sh
argument (somewhat analogous to
in Perl) provides a quick way to refer to the first file that changed.
When a single file is listed this is a handy way to avoid typing a
$ ls *.sql | entr psql -f /_
In the 2.9 release, a directory watch option (
-d) was added to react to events when a new file is added to a
directory. It was determined early on that
would not implement its own file search syntax, relying on standard Unix
tools instead. The implication of this is that if a new file appears, it
must exit and allow an external shell loop to rescan the file system.
way to implement this feature would be to simply require the users to list
will infer the directories if they aren't listed explicitly
$ while true; do > ls -d src/*.py | entr -d ./setup.py > done
I have written as if incorporating automated responses can be accomplished without special demands on the Unix development environment, but in practice the ability to split a window into multiple panes is the key to making this workflow efficient. A window manager such as i3 or the terminal multiplexer tmux enables you to quickly split the screen so that you can see the results as you work.
steps automation up to the next level by enabling you to control
applications in other panes via keystrokes. This combination can be wired
up in any number of ways to create some very interesting auto-responders.
Consider the following
vimdiff -Ris started in the first pane to compare two files containing similar HTTP headers
entris started in the second pane, and watches for updates to these two files
tmux send-keys -t .0is invoked to send keystrokes to the pane running Vim
":windo e"is the Vim command for “read the file again in each window”
C-mcommits this action by sending the Return key
With this mechanism in place we can fetch and compare headers using any tool capable of printing output or writing to a file—no plugins or specialized functionality required.
Some architectural limitations are for good reasons, but it's not easy to see why a particular restriction applies.
flag cannot be used with an interactive task:
STDINon the child allows
entrto accept keyboard input.
entrwere to close it's own file descriptor to
STDINthere is no reliable and immediate way to determine when the child has terminated in order to restore keyboard input.
Tstate is confusing, so we closes STDIN to raise an error instead.