2

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.

3
  • 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.
    – nohillside
    Commented Oct 17, 2012 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
    Commented Oct 17, 2012 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. Commented Oct 18, 2012 at 21:25

2 Answers 2

7
+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.

2
  • My pleasure, I'm glad I was able to help.
    – jaume
    Commented Oct 20, 2012 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
    Commented Oct 23, 2012 at 22:50
1

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .