macoswatchinotify

Is there a command like "watch" or "inotifywait" on the Mac?


I want to watch a folder on my Mac and then execute a bash script, passing it the name of whatever file/folder was just moved into or created in the watched directory.


Solution

  • fswatch

    fswatch is a small program using the Mac OS X FSEvents API to monitor a directory. When an event about any change to that directory is received, the specified shell command is executed by /bin/bash

    If you're on GNU/Linux, inotifywatch (part of the inotify-tools package on most distributions) provides similar functionality.

    Update: fswatch can now be used across many platforms including BSD, Debian, and Windows.

    Syntax / A Simple Example

    The new way that can watch multiple paths - for versions 1.x and higher:

    fswatch -o ~/path/to/watch | xargs -n1 -I{} ~/script/to/run/when/files/change.sh
    

    Note: The number output by -o will get added to the end of the xargs command if not for the -I{}. If you do choose to use that number, place {} anywhere in your command.

    The older way for versions 0.x:

    fswatch ~/path/to/watch ~/script/to/run/when/files/change.sh
    

    Installation with Homebrew

    As of 9/12/13 it was added back in to homebrew - yay! So, update your formula list (brew update) and then all you need to do is:

    brew install fswatch
    

    Installation without Homebrew

    Type these commands in Terminal.app

    cd /tmp
    git clone https://github.com/alandipert/fswatch
    cd fswatch/
    make
    cp fswatch /usr/local/bin/fswatch
    

    If you don't have a c compiler on your system you may need to install Xcode or Xcode command line tools - both free. However, if that is the case, you should probably just check out homebrew.

    Additional Options for fswatch version 1.x

    Usage:
    fswatch [OPTION] ... path ...
    
    Options:
     -0, --print0          Use the ASCII NUL character (0) as line separator.
     -1, --one-event       Exit fsw after the first set of events is received.
     -e, --exclude=REGEX   Exclude paths matching REGEX.
     -E, --extended        Use exended regular expressions.
     -f, --format-time     Print the event time using the specified format.
     -h, --help            Show this message.
     -i, --insensitive     Use case insensitive regular expressions.
     -k, --kqueue          Use the kqueue monitor.
     -l, --latency=DOUBLE  Set the latency.
     -L, --follow-links    Follow symbolic links.
     -n, --numeric         Print a numeric event mask.
     -o, --one-per-batch   Print a single message with the number of change events.
                           in the current batch.
     -p, --poll            Use the poll monitor.
     -r, --recursive       Recurse subdirectories.
     -t, --timestamp       Print the event timestamp.
     -u, --utc-time        Print the event time as UTC time.
     -v, --verbose         Print verbose output.
     -x, --event-flags     Print the event flags.
    
    See the man page for more information.