10

Is there a program that will automatically re-run, eg, make, when files are modified?

For example, when I'm writing sphinx documentation, it would be nice if make html was run automatically each time I edit any relevant files.

Jeff Atwood
  • 63,320
  • 48
  • 150
  • 153
David Wolever
  • 148,955
  • 89
  • 346
  • 502

7 Answers7

12

For simple things, rerun could be a good fit: http://pypi.python.org/pypi/rerun

"Command-line executable Python script to re-run the given command every time files are modified in the current directory or its subdirectories."

It requires a Python interpreter, but does not care if your command or files are written in Python.

Usage

rerun [--help|-h] [--verbose|-v] [--ignore|-i=<file>] [--version] <command>
Where:

<command>           Command to execute
--help|-h           Show this help message and exit.
--ignore|-i=<file>  File or directory to ignore. Any directories of the
                    given name (and their subdirs) are excluded from the
                    search for changed files. Any modification to files of
                    the given name are ignored. The given value is
                    compared to basenames, so for example, "--ignore=def"
                    will skip the contents of directory "./abc/def/" and
                    will ignore file "./ghi/def". Can be specified multiple
                    times.
--verbose|-v        Display the names of changed files before the command
                    output.
--version           Show version number and exit.
Walker Hale IV
  • 3,252
  • 2
  • 21
  • 11
  • Can be installed with apt on ubuntu systems: apt install rerun – JFL Sep 14 '19 at 06:54
  • According to [their own project description](https://pypi.org/project/rerun/): “In most circumstances, this project is superceded by [rerun2](https://github.com/tartley/rerun2) a ten-line Bash script” – Denilson Sá Maia Apr 24 '23 at 12:27
6

In Linux, you can use this command line:

while true; do inotifywait -e close_write  *.py; make; done

Uses standard system command inotifywait, if not available, install with something like:

sudo apt install inotify-tools
arauzo
  • 185
  • 1
  • 7
  • Because the question isn't tagged with linux, and might even be running on Windows, it it would help if you mention what OS this solution is for. – Patrick M Dec 01 '17 at 20:57
  • It is true. Thanks. I did not realize I wasn't in askubuntu. – arauzo Dec 01 '17 at 21:28
4

Well, since make will not do anything if nothing has changed, how about

while true; do sleep 60; make html; done

or the equivalent in your shell of choice? I don't think the usual file system layers are event-driven in such a way that they will you notify you of file changes without doing some similar themselves, but it's possibly DBUS can do that sort of stuff.

Ulrich Schwarz
  • 7,598
  • 1
  • 36
  • 48
  • 1
    D'oh. Of course. The only problem with that is that it would make errors harder to read (ie, because they would scroll up half way through reading them). – David Wolever Dec 07 '10 at 19:11
  • @David Wolever: "make html || sleep 900" should fix that. – Ulrich Schwarz Dec 07 '10 at 19:14
  • Awe… But then I've got to wait 900 after I fix the error. And, hey! Are you saying it would take me 15 minutes to fix errors?! ;) – David Wolever Dec 07 '10 at 19:33
  • @David Wolever: been a while since I had misbehaving shell scripts... wouldn't the first Ctrl-C just interrupt the sleep and send you back into the loop? I know stubborn scripts take a good bashing (oh dear, what an awful pun) on the keys to interrupt. – Ulrich Schwarz Dec 07 '10 at 20:43
  • hahah :D But, yes, a ^C would put me back into the loop… But then I'm switching back to the terminal, which is what I'd like to avoid. – David Wolever Dec 07 '10 at 23:11
  • Good incentive to make less errors. :D OK, I have nothing constructive to add at this point. – Ulrich Schwarz Dec 08 '10 at 05:38
  • AFAIK, Make can do a lot of work even if nothing changed. You are assuming that the build succeeded. Is there a way to tell Make to do nothing if nothing changed, even if the previous build failed? – Abhishek Anand Jan 21 '15 at 17:46
2

As per answer https://stackoverflow.com/a/22907316/71522 watchman seems to work very well:

 $ watchman-make -p '*.c' 'Makefile' -t all

Will re-run make all each time any *.c or Makefile file changes.

It can be installed with:

$ brew install watchman
Community
  • 1
  • 1
David Wolever
  • 148,955
  • 89
  • 346
  • 502
2

You could use inotifywait in a loop: https://github.com/rvoicilas/inotify-tools/wiki/#info

singpolyma
  • 10,999
  • 5
  • 47
  • 71
1

You could use incron: http://inotify.aiken.cz/?section=incron&page=about&lang=en

singpolyma
  • 10,999
  • 5
  • 47
  • 71
0

This question was also asked here: https://superuser.com/questions/181517/how-to-execute-a-command-whenever-a-file-changes/

You could try reflex

# Rerun make whenever a .c file changes
reflex -r '\.c$' make
Community
  • 1
  • 1
masterxilo
  • 2,503
  • 1
  • 30
  • 35