entr(1)

Run arbitrary commands when files change

overview | download 1.9

EXEC mode

Recompile if a source file changes

$ find . -name '*.c' | entr make

FIFO mode

Convert individual Markdown files to HTML if they're modified

$ ls *.md | entr +notify &
$ while read F; do
>   markdown2html $F
> done < notify

Theory and Operation

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 gv ship with a -watch option with reloads the document whenever the source file is modified. This is useful, but it's even better for applications to provide a programmatic means of refreshing the display. The browser add-on LiveReload has attempted to solve this problem for web developers by injecting JavaScript that listens on a web socket. The solution doesn't need to be this complex, indeed web pages can be opened or reloaded in xombrero using a a UNIX socket

$ ls *.css *.html | entr xombrero -e "reload"

It's not uncommon for modern web frameworks to continuously hunt for file system changes and refreshes the page when run in single threaded or standalone mode. Contrast this with common UNIX daemons which simply respond to signals. The following will reload nginx every time it's configuration is modified

$ ls /etc/nginx/nginx.conf | entr pkill -HUP nginx

In general, entr avoids special purpose options that can easily emulated using inline commands, for example one-shot mode can be emulated by running sh -c 'kill $PPID'. However, the need to kill and restart a process is a very common development task, so an auto-reload feature was added in the 1.9 release, and is enabled using the -r flag:

$ ls *.rb | entr -r ruby main.rb

This will,

  1. immediately start the server
  2. block until any of the listed files change
  3. terminate the background process
  4. wait for the server to exit before restarting

Unlike guard, entr is a zero-configuration tool with no dependencies (except on Linux, which requires libkqueue). The interface to entr is not only minimal, it aims to be simple enough to create a new category of ad hoc automation. These micro-tests reduce keystrokes, but more importantly they emphasize the utility of automated checks.

Tightening the edit-debug feedback loop requires a tool that is tuned for one task. inotifywait is light on dependencies, but it only works on Linux, and it's broad feature set doesn't provide a direct means of saying "run this command if any of these files change". This could be scripted, but there are a number of conditions to contend with:

  1. It's not uncommon for version control software to update a large set of files when they're submitted, but we don't want to spawn a new task for every file that is modified. To combat this entr ignores events until the subprocess ends.
  2. Some applications attempt to make saving a file atomic by writing a new file and then removing the original. entr deals 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.
  3. Editors such as VIM support many nifty file processing facilities, but command line instructions require a terminal. entr accommodates this requirement by attempting to open a TTY before entering it's event loop. xargs on BSD provides this functionality using the -o flag.

Last Updated May 17, 2013. Send questions or comments to eradman@entrproject.org