How to automatically watch for file changes and perform a custom action inside shell?

Solution 1:

The $25 Codekit does watch folders and files for changes and does compress/minify/combine JavaScript and CSS files.

I know this is only a partial answer for your question, as it is not a generic watcher, but it does fit your example:

whenever I edit a JavaScript source file to output a compressed version

Solution 2:

Watching a file for changes can be accomplished with a LaunchAgent. For example create a plist file at ~/Library/LaunchAgents/watch.and.lol.plist and fill it with this content:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>watch.and.lol</string>
    <key>ProgramArguments</key>
    <array>
        <string>/Users/Shared/changeAction.sh</string>
        <string>-force</string>
    </array>
    <key>WatchPaths</key>
    <array>
        <string>/private/var/radmind/client/.radmindOnDemand</string>
    </array>
</dict>
</plist>

Now make sure that the file /private/var/radmind/client/.radmindOnDemand does exist. Then load the launchagent with command $ launchctl load ~/Library/LaunchAgents/watch.and.lol.plist. As soon as the file ~/Library/LaunchAgents/watch.and.lol.plist does no longer exist, this launchagent job will be unloaded.

Now write some shell script that watches your file for changes, like:

chsum1=""

while [[ true ]]
do
    chsum2=`md5 /private/var/radmind/client/.radmindOnDemand`
    if [[ $chsum1 != $chsum2 ]] ; then           
        compile
        chsum1=`md5 /private/var/radmind/client/.radmindOnDemand`
    fi
    sleep 2
done

Note: this shell script needs some extra work to be done to make it efficient. Now it polls every 2 seconds (sleep 2). Better is to exit the script after the compile command has executed. That requires the storage of the output of the md5 hash command that can survive the exit and relauch of this shell script.