rsync , безумовно, є правильним інструментом для цієї роботи. Він існує для того, щоб синхронізувати каталоги синхронізовано, і це можна зробити з досить розумними. Наприклад: він передаватиме лише дельти, коли тільки може, і може працювати над ssh-тунелями.
Скажімо, у вас є джерело машини, яке розміщує вашу живу версію дерева каталогів /my/tree
та раковину машини, яку ви хочете підтримувати з нею тісною синхронізацією. Якщо у вас був обліковий запис ssh на раковині, ви могли з джерела використовувати rsync таким чином:
rsync -avz --delete -e ssh /my/tree/ remoteuser@sink:/my/tree
Це передбачає, що ви хочете /my/tree
в точно такому ж місці на раковині, як і у джерелі . Звичайно, не потрібно тримати його в точно такому ж місці.
Розбивка командного рядка:
-avz
: архівний режим, багатослівний вихід, використання стиснення під час передачі
--delete
: видалити файли під час синхронізації , які відсутні у вихідному коді
-e ssh
: Використовуйте ssh як метод з'єднання
Цей дзвінок, звичайно, запитає вас про пароль, коли ви його здійснюєте. Якщо ви хочете зробити це автоматичним способом, вам потрібно буде поділитися деякими ключами між обліковими записами на машинах і використовувати шифрування публічно-приватного ключа для створення ssh-з'єднання.
Щоб налаштувати свою пару ключів для цього rysnc, запустіть таку команду на своїй вихідній машині:
> ssh-keygen -t rsa -b 2048 -f ~/.ssh/my-rsync-key
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): [press enter here]
Enter same passphrase again: [press enter here]
Your identification has been saved in ~/.ssh/my-rsync-key.
Your public key has been saved in ~/.ssh/my-rsync-key.pub.
The key fingerprint is:
2e:28:d9:ec:85:21:e7:ff:73:df:2e:07:78:f0:d0:a0 root@source
> chmod 600 ~/.ssh/my-rsync-key
Щоб ця кнопкова робота працювала, нам потрібно додати вміст файлу ~/.ssh/my-rsync-key.pub
до ~<remoteuser>/.ssh/authorized_keys
файлу на раковині .
Спочатку скопіюйте файл на машину мийки :
scp ~/.ssh/my-rsync-key.pub remoteuser@sink:~
Потім ssh на машину мийки та імпортуйте ключ, запустивши на пристрої наступне в якості віддаленогокористувача :
> if [ ! -d ~/.ssh ]; then mkdir ~/.ssh ; chmod 700 ~/.ssh ; fi
cd ~/.ssh/
if [ ! -f authorized_keys ]; then touch authorized_keys ; chmod 600 authorized_keys ; fi
cat ~/my-rsync-key.pub >> authorized_keys
rm ~/my-rsync-key.pub
Додаткові поради з блокування з'єднання SSH між вашим джерелом і мийкою машинами я рекомендую подивитися на цій сторінці .
На вашій вихідній машині ви можете перевірити, що ця установка працює, запустивши:
rsync -avz --dry-run -e "ssh -i ~/.ssh/my-rsync-key" /my/tree/ remoteuser@sink:/my/tree
Це зробить сухий цикл rsync. Якщо ви бачите команду rsync, що з'єднує та порівнює файли, ви знаєте, що налаштування налаштовано належним чином.
Тепер нам потрібен простий спосіб викликати цю команду rsync з конфігураційного файла LaunchD, як показано в цій корисній відповіді на цьому сайті . Оскільки ви хочете, щоб цей дзвінок відбувався в тісному циклі, вам потрібно буде переконатися, що у вас немає декількох копій rsync, що працює одночасно. Ви можете використовувати flock для створення файлу mutex, який забезпечує, що bash-скрипт є однотонним: лише один екземпляр його запускається одночасно на машині. Отже, ми збираємось створити наступний скрипт на диску:
#!/bin/sh
SINK_INSTANCE=remoteuser@sink
DIR=/my/tree
KEY=~/.ssh/my-rsync-key
LOG = ~/my_rsync.log
LOCK = ~/my_rsync.lock
SOURCE=/my/tree
exec 9>${LOCK}
if ! flock -n 9 ; then
echo "Another instance of your rsync is already running";
exit 1
fi
echo "----------" >> ${LOG}
echo `date` >> ${LOG}
rsync -avz --delete -e "ssh -i ${KEY}" \
${SOURCE}/ {SINK_INSTANCE}:${SOURCE} 2>&1 >> ${LOG}
Збережіть це як ~/my_rsync.sh
.
Цей сценарій піклується про те, щоб зробити rsync для вас. Все, що вам потрібно зробити зараз, це налаштувати його за допомогою LaunchD і запустити його в тісний цикл. Виконуючи вказівки звідси та змінюючи його, щоб відповідати нашим потребам, ми збираємось створити ~/Library/LaunchAgents/my-rsync.plist
текстовий редактор і зробити вміст:
<?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>My Rsync</string>
<key>Program</key>
<string>/bin/sh</string>
<key>ProgramArguments</key>
<array>
<string>sh</string>
<string>-c</string>
<string>while sleep 5s; /Users/my/my_rsync.sh; done</string>
</array>
<key>ServiceDescription</key>
<string>Keep /my/tree synchronized with the machine sink</string>
<key>KeepAlive</key>
<true/>
</dict>
</plist>
Це має подбати про речі.
Застосовуються звичайні застереження: я написав це з пам'яті і не перевіряв. Тому не слідкуйте сліпо. Тестуйте ретельно по дорозі. Щоразу, коли ви сумніваєтесь, використовуйте --dry-run
опцію на rsync. Він надрукує те, що зробив би , фактично нічого не роблячи.