How do you execute a command when a file is changed?
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.
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).