You could use launchd
.
launchd
lets you manage daemons and agents according to certain conditions.
What are daemons and agents?
From man launchd
:
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.
From http://developer.apple.com/library/mac/#technotes/tn2083/_index.html:
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
other programs.
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:
/tmp/folderstuart
/tmp/folderstuartsfriend
and this is the common folder for the application:
/tmp/folder
We want to monitor the two paths above and synchronize their contents with /tmp/folder
.
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">
<plist version="1.0">
<dict>
<key>Label</key>
<string>notesfoldersync</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/rsync</string>
<string>-aE</string>
<string>--delete</string>
<string>--exclude='.*'</string>
<string>/tmp/folderstuart/</string>
<string>/tmp/folderstuartsfriend/</string>
<string>/tmp/folder</string>
</array>
<key>WatchPaths</key>
<array>
<string>/tmp/folderstuart</string>
<string>/tmp/folderstuartsfriend</string>
</array>
<key>ThrottleInterval</key>
<integer>10</integer>
</dict>
</plist>
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 .localized
, .DS_Store
and other hidden files.
I added 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:
/System/Library/LaunchDaemons/notesfoldersync.plist
Create:
/tmp/folderstuart
/tmp/folderstuartsfriend
/tmp/folder
and load (that is, enable) the plist:
sudo launchctl load /System/Library/LaunchDaemons/notesfoldersync.plist
Now create a file in /tmp/folderstuart
:
touch /tmp/folderstuart/file.txt
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 /tmp/folderstuartsfriend
.
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.
Best Answer
TextEdit (and other apps that use the autosave system) will automatically save snapshots of documents at various times (e.g. when they're opened but before they're changed). Reopen the document in TextEdit, then from the File menu choose Revert To. It'll have a submenu that might have a relevant snapshot listed that you can choose directly. If not, choose Browse All Versions. You'll get a Time-Machine-like history on the right side of the screen, and you can look for the latest good version, then when you find what you want click Restore.
See this OWC/MacSales article, this one at OS X Daily, and this Apple support guide for more details and options.