I'm looking for a way to rerun a specific command as soon as any of the files in a subdirectory (perhaps minus selected excludes) changes.
Use case
I'm working on a project that is self-contained in a directory. This project can be compiled, say, using make
. I want to use the idle time of my machine to repeatedly compile the project. One option is to call make
once per second, e.g., using watch (1)
. However, if make
fails, it will usually fail whenever it's executed again, thus wasting CPU processing power (and, more importantly, heating up my laptop computer).
Instead, there should be a process that watches all files and runs make
(or whatever other tool) only after anything changes in the directory where the project lives.
Existing solutions
Others have asked: Can a bash script be hooked to a file? There's inotifywait (1)
, but it doesn't appear to have a nice interface for repeating a command. Also, there's entr (1)
which looks like the way to go, but a closer inspection of the project's website reveals that
[i]t was determined early on that
entr
would not implement it's own file search syntax, relying on standard Unix tools instead.
I'm lazy. I don't want to write a loop for my repeated invocation of make
. Is there a higher-level magic tool that allows me to write
magic make
with the effect that make
is rerun everytime anything in the current directory changes?
NB: It would be ideal if this magic tool was aware of the inevitable race condition that ensues when using inotify
: Changes that occur after issuing the call but before a watch is established. I'm not sure if entr
can do this, it looks like this feature requires keeping track of some kind of snapshot of at least the timestamps of all affected files.
SHAMELESS SELF-PROMOTION: My own four-liner that (somewhat) accomplishes this is called rpt
and is far from perfect, I'd like to know if I'm duplicating effort here.
cron
(to start check) + find (to modification check).cron
(which can start check every minute), usewatch
instead (to check every second).