You could use
launchd lets you manage daemons and agents according to certain conditions.
What are daemons and agents?
A "daemon" is, by definition, a system-wide service of which there is
one instance for all clients. An
"agent" is a service that runs on a per-user basis. Daemons should not attempt to display UI or interact directly with a user's
login session. Any and all work that involves interacting with a user should be done through agents.
Daemons and agents, collectively known as background programs, are
programs that operate without any graphical user interface. As a
developer, you can use background programs to perform actions without
user interaction, and also to manage a shared state between multiple
The difference between an agent and a daemon is that an agent can
display GUI if it wants to, while a daemon can't. The difference
between an agent and a regular application is that an agent typically
displays no GUI (or a very limited GUI).
The daemon/agent is described in an XML file with extension plist. One of the conditions that can be monitored is changes in a folder. This will come in handy.
OK, let's get our hands dirty:
Let's say these are the 2 folders where you and your friend keep your files:
and this is the common folder for the application:
We want to monitor the two paths above and synchronize their contents with
This is the plist that does what we need:
<?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">
The plist monitors the two folders with key
WatchPaths (see http://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html#//apple_ref/doc/uid/10000172i-SW7-SW8).
I suggest the program
rsync for synchronizing folders. Option
--delete ensures that files deleted in the monitored folders are also deleted in
/tmp/folder. Other options are
-aE to copy standard and extended HFS+ attributes, and
--exclude='.*' to skip
.DS_Store and other hidden files.
ThrottleInterval in case you want to set the minimum interval a job can be spawned. Default value is 10 s, that is, jobs will not be spawned more than once every 10 seconds.
Save the plist (see
man launchd for a list of possible paths) as:
and load (that is, enable) the plist:
sudo launchctl load /System/Library/LaunchDaemons/notesfoldersync.plist
Now create a file in
and watch the magic happen:
file.txt will be created within seconds in
/tmp/folder. Delete it and it will disappear from
/tmp/folder. It will also synchronize files created or deleted in
Notice that this solution doesn't handle name collisions! If you can't ensure that files will be named differently substitute rsync with a script that rsyncs and does file name checking to avoid data loss.
If copying files is not an option, substitute
rsync with a script that creates hardlinks (if both files are in the same filesystem I'd recommend hardlinks instead of symlinks). Before changing the plist unload it:
sudo launchctl unload /System/Library/LaunchDaemons/notesfoldersync.plist
When you're done, load it again.