I want to make a shell script that runs any time the contents of a particular folder on my server are changed. Seems easy enough at first, because launchd has a directive called WatchPaths which triggers your script any time the contents of a folder change.

HOWEVER WatchPaths is not triggered by changes in subfolders. The folder I'm trying to watch is a few hundred MB of small web files, nested several levels deep in sub folders. Far too many folders to try to manually list each one.

Is there some other sane way to accomplish this?

  • The problem is, the root folder hasn't changed, no matter what you do to sub folders. What exactly are you attempting to do? This sounds like a long way around to do something.
    – Allan
    Feb 19 '19 at 0:44
  • I want to have a folder that permanently lives on disk, and I want to copy it to a RAM disk every time something in the folder, anything in the folder, changes. I know I could do the whole thing by timer, or with a manual 'button'. But both of those solutions have drawbacks that WatchPaths would solve completely.... if it could see into subfolders too.
    – l008com
    Feb 19 '19 at 1:10

WatchPaths doesn't appear to be able to watch a sub-directory recursively, so the best you can do with it is watch a single directory's activities. You might want to take a look at Folder Actions, they're discussed in detail in this blog post titled: Setup OS X Folder Actions to Know When a File is Added as well.

Another alternative is to use a CLI tool that's available in Homebrew via the brew install fswatch command. fswatch is a cross platform implementation that works on most flavors of *NIX includes macOS.

The FSEvents monitor, available only on OS X, has no known limitations, and scales very well with the number of files being observed.


Here I've created a sub-directory called ~/somedir. I then invoked `fswatch against this directory:

$ mkdir ~/somedir
$ fswatch /some/dir

Now if we start adding files and sub-directories fswatch will notify:

$ touch ~/somedir/afile
fwatch msg>> /Users/joeuser/somedir/afile

$ mkdir ~/somedir/anotherdir
fswatch msg>> /Users/joeuser/somedir/anotherdir

$ touch ~/somedir/anotherdir/afile
fswatch msg>> /Users/joeuser/somedir/anotherdir/afile

The above can be adapted for use in a shell script which can take whatever other actions you require when any changes are detected against the directory tree that fswatch is monitoring.

Other Examples

To act on file system activity you can use one of these 2 patterns:

$ fswatch -0 path | while read -d "" event \
  do \
    // do something with ${event}

Or this:

$ fswatch -o path | xargs -n1 -I{} program


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .