Вы могли бы использовать launchd
.
launchd
позволяет управлять демонами и агентами в соответствии с определенными условиями.
Что такое демоны и агенты?
От man launchd
:
«Демон» по определению является общесистемной службой, для которой существует один экземпляр для всех клиентов. «Агент» - это служба, которая работает для каждого пользователя. Демоны не должны пытаться отображать пользовательский интерфейс или напрямую взаимодействовать с сеансом входа пользователя в систему. Любая работа, связанная с взаимодействием с пользователем, должна выполняться через агентов.
От http://developer.apple.com/library/mac/#technotes/tn2083/_index.html :
Демоны и агенты, известные как фоновые программы, - это программы, которые работают без какого-либо графического интерфейса пользователя. Как разработчик, вы можете использовать фоновые программы для выполнения действий без взаимодействия с пользователем, а также для управления общим состоянием между несколькими другими программами.
Разница между агентом и демоном заключается в том, что агент может отображать графический интерфейс, если хочет, а демон - нет. Разница между агентом и обычным приложением заключается в том, что агент обычно не отображает графический интерфейс (или очень ограниченный графический интерфейс пользователя).
Демон / агент описан в XML-файле с расширением plist. Одним из условий, которые можно отслеживать, являются изменения в папке . Это пригодится.
Хорошо, давайте запачкаем руки:
Допустим, это две папки, где вы и ваш друг храните ваши файлы:
/tmp/folderstuart
/tmp/folderstuartsfriend
и это общая папка для приложения:
/tmp/folder
Мы хотим отслеживать два пути выше и синхронизировать их содержимое с /tmp/folder
.
Это тот список, который делает то, что нам нужно:
<?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>
Plist контролирует две папки с ключом WatchPaths
(см. Http://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html#//apple_ref/doc/uid/10000172i-SW7 -SW8 ).
Предлагаю программу rsync
для синхронизации папок. Опция --delete
гарантирует, что файлы, удаленные в контролируемых папках, также будут удалены в /tmp/folder
. Другие опции -aE
для копирования стандартные и расширенные атрибуты HFS +, и --exclude='.*'
пропустить .localized
, .DS_Store
и другие скрытые файлы.
Я добавил ThrottleInterval
на тот случай, если вы хотите установить минимальный интервал, когда может быть запущена работа. Значение по умолчанию - 10 с, то есть задания будут создаваться не чаще, чем раз в 10 секунд.
Сохраните список (см. man launchd
Список возможных путей) как:
/System/Library/LaunchDaemons/notesfoldersync.plist
Создайте:
/tmp/folderstuart
/tmp/folderstuartsfriend
/tmp/folder
и загрузить (то есть включить) список:
sudo launchctl load /System/Library/LaunchDaemons/notesfoldersync.plist
Теперь создайте файл в /tmp/folderstuart
:
touch /tmp/folderstuart/file.txt
и смотреть, как происходит волшебство: file.txt
будет создано в течение нескольких секунд /tmp/folder
. Удалите его, и он исчезнет из /tmp/folder
. Он также будет синхронизировать файлы, созданные или удаленные в /tmp/folderstuartsfriend
.
Обратите внимание, что это решение не обрабатывает конфликты имен! Если вы не можете гарантировать, что файлы будут иметь разные имена, замените rsync на скрипт, который rsyncs и выполняет проверку имени файла, чтобы избежать потери данных.
Если копирование файлов не является вариантом, замените rsync
его сценарием, который создает жесткие ссылки (если оба файла находятся в одной файловой системе, я бы рекомендовал жесткие ссылки вместо символических ссылок). Прежде чем менять лист, выгрузите его:
sudo launchctl unload /System/Library/LaunchDaemons/notesfoldersync.plist
Когда вы закончите, загрузите его снова.