The problem

I am doing a project in a language that is not nodejs and I want to have a tool that monitors a directory for file changes and re-run a command every time a file changes. The can can be anything like:

  • a python script
  • a shell script
  • a makefile
  • a docker-compose command
  • a bash script
  • a ruby script
  • any other command or combination of the above

What is nodemon

nodemon is a tool that helps you develop node.js apps by automatically restarting the node application when file changes in the directory are detected.

It speeds up the development process as you don’t have to manually restart the application every time you make a change.

Nodemon limitations

It is a nodejs specific tool and only works with node applications. You can find ways of making it work with other languages, but it is not as straightforward and tailored as it is for node.

You must have it installed and with it many nodejs dependencies that you may not need for your project.

Alternative to nodemon: entr

I stumbled upon entr that is a general purpose file watcher and I am using it for a while now to re-run commands on file changes.

It it a Linux command so it also run Windows via WSL (Windows Subsystem for Linux).

Reload your project on each change, monitor specific files
Reload your project on each change, monitor specific files

Install it with:

sudo apt install entr

And use it like this:

find . -name '*.py' | entr python myscript.py

In the example above, it will monitor all python files in the current directory and subdirectories and run python myscript.py every time a file changes.

You can also make it more versatile by adding the command to a makefile like:

watch:
    find . -name '*.py' | entr python myscript.py

I did something even more generic that watches all files, so that anything I change in the project root directory will trigger a command:

# monitor changes in the parent directory and re-run a command every time any file changes
# in this case, the command is to run a python script
mon:
        find .. | entr poetry run python3 90_prepare_hugo_files.py

Using this generic approach I have the realtime feedback I need to develop my project in any language, meaning I am more productive.

Other interesting usages

I have used this to:

  • reload docker containers when I change files that are used to build then
  • re-run a python script inside a container when files changed in a mapped volume
  • push changes to git any time I save an specific file: super time saver to keep things in sync
  • starting automation just by editing specific files

Cron and systemd are a subject for another post, but you can use them to start the entr command at boot time and keep it running all the time.