TIL: Auto-reload a command when files changed using entr
While working with Go and JavaScript, we have tools available for auto reloading the server when the code changes. For JavaScript, we even have hot reload which reloads part of the page without reloading the whole page. But for Python, we don’t have such tools, I tried livereload, but it does not work well for nested directories. So I decided to do it myself. And there is a tool called entr
which helps run a command when some file changes.
First, install entr
:
apt get entr
It can be used like this, which will run python main.py
when any file in the current directory changes, recursively:
find . | entr -r python main.py
But this will only work for changes in existing files, not for new files. To fix this, we can combine with some tricks. Let’s use ls -alR | sha256sum
to get a hash of all files in the current directory recursively. And then we can compare the hash to see if any file has changed:
hash() {
ls -alR | sha256sum
}
hash0="$(hash)"
echo "$hash0" > /tmp/hash.txt
while true; do
hash1="$(hash)"
if [[ "$hash0" != "$hash1" ]]; then
hash0="$hash1"
echo "$hash1" > /tmp/hash.txt
fi
done
Here is the final code, enjoy!
#!/bin/bash
hash() {
ls -alR | grep '\.py$' | sha256sum
}
watch() {
hash0="$(cat /tmp/hash.txt)"
while true; do
hash1="$(hash)"
if [[ "$hash0" != "$hash1" ]]; then
printf "\n\n------- restarting server -------\n\n"
hash0="$hash1"
echo "$hash1" > /tmp/hash.txt
fi
sleep 2
done
}
if [[ -z "$DEBUG" ]]; then
echo "$(hash)" > /tmp/hash.txt
watch &
echo '/tmp/hash.txt' | entr -r python apps/rpc/app/main.py
else
python -m debugpy --listen 0.0.0.0:12345 apps/rpc/app/main.py
fi
Let's stay connected!
Author
I'm Oliver Nguyen. A software maker working mostly in Go and JavaScript. I enjoy learning and seeing a better version of myself each day. Occasionally spin off new open source projects. Share knowledge and thoughts during my journey. Connect with me on , , , , or subscribe to my posts.