It’s often beneficial to trigger a specific command when a file is updated. For instance, when I write stuff in LaTeX I like to keep the resultant PDF open on one of my monitors to immediately see changes (and to see when I invariably mess up).
This means that I need to rebuild the PDF on every save.
A timed watch (e.g. every 30 seconds) works, as does a Gulp task using gulp-pdflatex[1] – though gulp is a bit heavyweight for such a simple task; it just feels wrong to pull in 8MB of node modules to run gulp watch
. And then you have a single case – a task that only works for pdflatex, too. I like a more general solution.
So to react on a save without having the weight of gulp I have a custom script that looks something like the following:
#!/bin/zsh inotifywait -e close_write,moved_to,create -m . | while read -r directory events filename; do if [ "$filename" = "resume.tex" ]; then xelatex resume.tex fi done
You’ll need inotify-tools (sudo apt install inotify-tools
) if you don’t have it already.
You can check the detail of what is possible in the inotifywait
man page. In short:
-e close_write,moved_to,create
The events we watch for. Full list in the man page forinotifywait
.-m .
monitor the current directory. Monitor also changesinotifywait
from exiting after the first event (default behaviour) to run indefinitely.read -r directory events filename;
inotifywait
outputswatched_filename EVENT_NAMES event_filename
. In case of a watched directory a trailing slash is output for watched_filenameif [ "$filename" = "resume.tex" ]; then
Make sure the file that changed is the file we are interested inxelatex resume.tex
Command we want to run on a change.
BTW, I originally had the inotifywait
line something like:
inotifywait -q -m -e close_write --format %e myfile.ext
The downside being that inotifywait
dies when the file is completely overwritten and many editors do exactly that.
So it’s easier to set up a watch on the whole directory that you are interested in and filter for specific files as done in the snippet above.
For interest, the --format %e
in the old command is to handle spaces in the watched filenames – it replaces the output with a user specified format (in this case %e
, return as comma-separated list of events).
Remember to chmod +x your script. Enjoy.