Make inotifywait a group of multiple file updates in one?

I have a folder with Sphinx documents that I look with inotifywait (from inotify-tools ). The script rebuilds html & singlehtml and updates 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 great when I save a single file. However, when I hg update an old revision or paste several files into the source folder, it runs a script for each individual file.

Is there a simple workaround (without writing custom Python scripts - I can do this) to make it wait a split second before running the script?

+6
source share
2 answers

I made a slightly more complex shell script and posted it in an 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 

This makes the inotifywait not only the file name and action, but also the inotifywait time. The script compares the timestamp with the current unixtime time, and if the delta is less than 2 seconds, it runs make html . But before that, he sleeps 1 second to complete file operations. For the following modified files, the timestamp will be old, the delta will be more than 2 seconds, and nothing will be done.

I found that this method consumes the least processor resources and is the most reliable.

I also tried to run a simple Python script, but that meant that if I inserted something as big as jQueryUI into the folder, thousands of processes were started and then turned into zombies.

+6
source

Try it:

 last_update=0 inotifywait -mr source --exclude _build -e close_write -e create \ -e delete -e move --format '%T' --timefmt '%s' | while read timestamp; do if test $timestamp -ge $last_update; then sleep 1 last_update=$(date +%s) make html singlehtml xdotool search --name Chromium key --window %@ F5 fi done 
  1. --format '%T' --timefmt '%s' triggers a timestamp for each event.
  2. test $timestamp -ge $last_update compares the test $timestamp -ge $last_update event label with the timestamp of the last update. Any events that occurred during sleep are thus skipped.
  3. sleep 1 added to wait for events to accumulate. A shorter duration may be good, for example, sleep 0.5 , but it will be less tolerable.
  4. last_update=$(date +%s%N) sets the timestamp of the last update, which will be compared with the timestamp of the next event. Thus, any additional events that occur during sleep 1 are discarded during the next iteration of the loop.

Note that there is a race condition here because strftime () does not support nanoseconds. This example can run make twice if an event group crosses a second border. Instead, risk skipping events, replace -ge with -gt .

+1
source

All Articles