I want a quick and simple way to execute a command whenever a file changes I want something very simple that i leave running on a terminal and close it when i'm finished working with this file

I'm using this right now

while read; do ./myfile.py ; done

And then I need to go to that terminal and press Enter , whenever I save that file on my editor. What i want is something like this

while sleep_until_file_has_changed myfile.py ; do ./myfile.py ; done

Or any other solution as easy as that.

I'm using vim and i know i can add an autocommand to run something on bufwrite but this is not the kind of solution i want now

Update: I want something simple, discardable if possible. What's more i want something to run in a terminal because i want to see the program output i want to see the error messages

About the answers: Thanks for all your answers! All of them are very good, and each one takes a very different approach from the others. Since i need to accept only one, i'm accepting the one that i've actually used (it was simple, quick and easy-to-remember), even though i know it is not the most elegant.

Best Answer


Simple, using inotifywait (install your distribution's inotify-tools package).

while inotifywait -e close_write myfile.py; do ./myfile.py; done

or

inotifywait -q -m -e close_write myfile.py |
while read -r filename event; do
  ./myfile.py         # or "./$filename"
done

The first snippet is simpler, but it has a significant downside: it will miss changes performed while inotifywait isn't running (in particular while myfile is running). The second snippet does not have this defect However it assumes that the file name doesn't contain whitespace If that's a problem, use the --format option to change the output to not include the file name.

inotifywait -q -m -e close_write --format %e myfile.py |
while read events; do
  ./myfile.py
done

Either way, there is a limitation: if some program replaces myfile.py with a different file, rather than writing to the existing myfile , inotifywait will die. Many editors work that way

To overcome this limitation, use inotifywait on the directory.

inotifywait -e close_write,moved_to,create -m . |
while read -r directory events filename; do
  if [ "$filename" = "myfile.py" ]; then
    ./myfile.py
  fi
done

Alternatively, use another tool that uses the same underlying functionality, such as incron (lets you register events when a file is modified) or fswatch (a tool that also works on many other Unix variants, using each variant's analog of Linux's inotify).