Photo by [Jenil Gogari](https://unsplash.com/@jgog?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)
on [Unsplash](https://unsplash.com/s/photos/timelapse?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)

Photo by Jenil Gogari on Unsplash

If you recompile often when writing software then you might tlike this little timesaver: automatically running a command whenever a file changes in a given file directory.

Introducing entr

Let me introduce you to a tool called entr. This tool uses kqueue and inotify to watch for file changes and is able to execute arbitrary commands. This allows us to run all kinds of commands during software development when source or configuration files change, for example:

  • build commands
  • test commands
  • restarting a server

You can also use it to set up a whole automation workflow. However, be aware of the increased complexity when chaining entr commands and their triggers together. I prefer to keep it simple and set the tool up as helpful helper to save me some time. And to get rid of repetitive, monotonous tasks. Because I don’t like repetitive, monotonous tasks.

Installation

On Linux use your package manager to install entr if not already installed:

sudo apt-get install entr

On Mac you can install entr with the Homebrew package manager:

brew install entr

Or you clone from its GitHub repository and build from source:

./configure
make test
make install

Unfortunately I could not test a solution for Windows, but the respository’s README mentions Windows and the WSL - which might be a reasonable workaround because inotify and kqueue do not exist within the Microsoft universe.

Usage

The entr tool offers a few options, as you can see from its synopsis:

entr [-acdnprsz] utility [argument /_ ...]

You can pipe the output of a command into entr to trigger a command, for example launching and and auto-reloading a node.js server whenever a Javascript file changes within the current directory:

ls *.js | entr -r node app.js

I had problems with the combination of the ls command and entr on Mac OS so I used the find command. The find command offers additional options for filtering which proved useful.

CMake Build and Test Example

Run from your build directory and use the -s option to pass chained commands:

find .. -name "*.h" -o -name "*.cc" | entr -s 'cmake --build . && ctest'

This command will watch changes in header or implementation files and start a build via CMake plus CTest run on success.

Cargo Build and Test Example

Run from your main directory and use the -s option to execute cargo build and test:

find .. -name "*.rs" | entr -s 'cargo build && cargo test'

Run a Single Python File

Execute a single Python file if this file changes by piping the echo command into entr:

echo main.py | entr python main.py

Command Manual

You can have a look at the manual to see all available options: man entr. I found the following options the most useful:

  • -c to clear the console and not having to scroll through old command output
  • -r to reload a whole process if something changes, for example a web server
  • -s to execute more complicated commands

I hope entr helps you to automate repetitive tasks and get your results faster. Keep on coding and keep on creating!