Take the 2-minute tour ×
Ask Different is a question and answer site for power users of Apple hardware and software. It's 100% free, no registration required.

I have an application which looks for its data (*.txt) files in a folder. I have two folders containing text data that I need to keep separate, but it would be useful to have the application see the text data files as residing in one folder (containing the two sets of files).

I can create a script that maintains symbolic links to the files in the two folders in a third combined folder.

Rather than reinventing the wheel, I'd like to use a proven solution if possible.

The solution would have to deal with the case of file name clashes in a sensible way.

share|improve this question
1  
What's unproven about the script solution? You'll need some coding to resolve name clashes anyway, Smart Folders alone don't help here. –  patrix Oct 17 '12 at 12:42
3  
Why do you need to keep the folders separate? To me it would seem easier to have one folder with the files (therefore your name clashes are handled when the files are created/gathered), and then to copy a symbolic link to one of the other two organizational folders. If there's an easy way to tell where they belong through a script this can be done with a Folder Action. –  ghoppe Oct 17 '12 at 23:34
    
My friend and I both have keep a folder of plain text notes. I want to include his notes in my folder but my notes don't interest him. Therefore, I want both of our notes in my folder without putting them in his folder. –  Stuart Woodward Oct 18 '12 at 21:25

2 Answers 2

up vote 7 down vote accepted
+50

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.

share|improve this answer
    
Thanks for your generous answer. –  Stuart Woodward Oct 20 '12 at 11:22
    
My pleasure, I'm glad I was able to help. –  jaume Oct 20 '12 at 17:17
    
@Stuart, while this answer is truly impressive, it has several limitation, so be sure you can live with them. In particular, the combined file folder /tmp/folder needs to be treated as read-only, because changes made there will not be propagated back to the other folders. Also, as jaume noted, name collisions will result in one file overwriting the other. With some work (manually editing the XML file) you could create a Smart Folder that contains .txt files from both folders. Would that work for your App? –  Old Pro Oct 23 '12 at 22:50

Why not use a keyword or Spotlight Comment to tag the files in each folder, and then a Smart Folder to show them together?

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.