entr
Using entr is the new way to do this (it's cross platform). Note entr doesn't use polling giving it a huge advantage over many of the alternatives.
Uses
kqueue(2)orinotify(7)to avoid polling.entrwas written to make rapid feedback and automated testing natural and completely ordinary.
On BSD it uses pledge(2)
You can install it with
apt-get install entr
dnf install entr
brew install entr
You can track a directory for new additions using
while $(true); do
# echo ./my_watch_dir | entr -dnr echo "Running trigger..."
echo ./my_watch_dir | entr -dnr ##MY COMMAND##
done;
Options explained (from the docs),
-dTrack the directories of regular files provided as input and exit if a new file is added. This option also enables directories to be specified explicitly. Files with names beginning with ‘.’ are ignored.-nRun in non-interactive mode. In this mode entr does not attempt to read from the TTY or change its properties.-rReload a persistent child process. As with the standard mode of operation, a utility which terminates is not executed again until a file system or keyboard event is processed.SIGTERMis used to terminate the utility before it is restarted. A process group is created to prevent shell scripts from masking signals.entrwaits for the utility to exit to ensure that resources such as sockets have been closed. Control of the TTY is not transferred the child process.
Note entr isn't polling there. It's after there is an operation on an inode it hasn't seen. Note this isn't a failsafe mechanism because the inode could be recycled to a different file name entirely. Ie,
mkdir foo;
cd foo;
touch bar;
touch baz;
ls -1i;
echo "delete bar; add quz"
rm bar;
touch quz;
ls -1i;
See the inotifywait answer for a better, and more powerful method of doing this. Albeit with a much worse interface.