Search code examples
shellinotifyinotify-tools

Make inotifywait group multiple file updates into one?


I have a folder with Sphinx docs that I watch with inotifywait (from inotify-tools). The script re-builds the html & singlehtml and refreshes Chrome.

#!/bin/sh
inotifywait -mr source --exclude _build -e close_write -e create -e delete -e move | while read file event; do
    make html singlehtml
    xdotool search --name Chromium key --window %@ F5
done

This works fine when I save a single file. However, when I hg update to an old revision or paste multiple files in source folder, it fires the script for every single file.

Is there a simple workaround (without writing custom python scripts -- this I can do) to make it wait a fraction of a second before firing the script?


Solution

  • I made a bit more complex shell script and posted it in the article:

    inotifywait -mr source --exclude _build -e close_write -e create -e delete -e move --format '%w %e %T' --timefmt '%H%M%S' | while read file event tm; do
        current=$(date +'%H%M%S')
        delta=`expr $current - $tm`
        if [ $delta -lt 2 -a $delta -gt -2 ] ; then
            sleep 1  # sleep 1 set to let file operations end
            make html singlehtml
            xdotool search --name Chromium key --window %@ F5
        fi
    done
    

    It makes inotifywait log not only filename & action, but also timestamp. The script compares the timestamp with current unixtime and if the delta is less than 2 sec, it runs make html. But before that it sleeps 1 second to let file operations end. For the next modified files the timestamp will be old, the delta will be more than 2 seconds, and nothing will be done.

    I found this way was the least CPU consuming and the most reliable.

    I also tried running a simple Python script, but this meant if I pasted something as big as jQueryUI into the folder, a thousand processes were spawned and then became zombies.