I have a little script that watches files for changes using inotifywait
. When something changes, a batch of files are sent through a process (compiled, compressed, reorganised, etc) that takes about ten seconds to run.
Consider the following example:
touch oli-test
inotifywait -mq oli-test | while read EV; do sleep 5; echo "$EV"; done
If you run touch oli-test
in another terminal a few times, you'll see that each loop completes before it moves on. That scenario is very real to me. If I forget to save a file while it's already processing, or notice a mistake, the events stack up and I'm waiting minutes.
It strikes me that there are two techniques that would make this workflow objectively better. I'm not sure what is easiest or best, so I'm presenting both:
Interrupt previous run-throughs, and restart immediately. The scripted process is currently just an inline set of commands. I could break them out to Bash functions, I'm not wild about breaking them further out than that.
Debounce the list of things waiting to be processed so that if five events happen at once (or while it's already processing), it only runs once more.
(Or both... because I'm certain there are cases where both would be useful)
I am also open to approaches that are different from inotifywait
but they need to give me the same outcome and work on Ubuntu.
To interrupt, you can shift things around so the processing runs in a background subshell and each new inotifywait
event nukes the background processes:
inotifywait -mq oli-test | while read EV; do
jobs -p | xargs kill -9
(
# do expensive things here
sleep 5 # a placeholder for compiling
echo "$EV"
) &
done
Here is a compact solution:
inotifywait -q -m -e modify -e create -e close_write --format "%w%f" /etc/nginx/ |\
while read -r path; do
echo $path changed
echo "Skipping $(timeout 3 cat | wc -l) further changes"
service nginx reload
done
The first read
waits for a line of data, so this won't eat your CPU. The timeout 3 cat
reads any further change notifications that come in over the next 3 seconds. Only then does nginx
get reloaded.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With