Мы хотели бы использовать unison
для синхронизации двух серверов. Из командной строки и в файлах bash следующая команда работает нормально:
unison -batch /var/www/html/test ssh://host-2//var/www/html/test
Файлы синхронизируются и unison.log
обновляются. Пока все хорошо.
в сочетании с файлом настроек, например, .unison/default.prf
и просто выполняя unison
из командной строки, как описаноздесь, все тоже работает отлично.
Мы также установили incrond
inotify cron daemon, и он работает гладко. Следующее задание cron выполняется просто отлично:
/var/www/html/test IN_MODIFY,IN_ATTRIB,IN_CREATE touch /root/test
/root/test
обновляется каждый раз, когда я вношу изменения в файлы в/var/www/html/test
Пока все хорошо! Но единственное, что не работает с использованием incrontab:
/var/www/html/test IN_MODIFY,IN_ATTRIB,IN_CREATE unison
/var/www/html/test IN_MODIFY,IN_ATTRIB,IN_CREATE /usr/bin/unison
/var/www/html/test IN_MODIFY,IN_ATTRIB,IN_CREATE /usr/local/sbin/unison
/var/www/html/test IN_MODIFY,IN_ATTRIB,IN_CREATE unison -batch /var/www/html/test ssh://host-2//var/www/html/test
/var/www/html/test IN_MODIFY,IN_ATTRIB,IN_CREATE /usr/bin/unison -batch /var/www/html/test ssh://host-2//var/www/html/test
/var/www/html/test IN_MODIFY,IN_ATTRIB,IN_CREATE /usr/local/sbin/unison -batch /var/www/html/test ssh://host-2//var/www/html/test'
В unison.log
файле ничего не отображается, не говоря уже об обновлении удаленного сервера. Следующий код также ничего не выводит.
/var/www/html/test IN_MODIFY,IN_ATTRIB,IN_CREATE unison &> /root/test.log
/root/test.log
даже не создается.
Другой тест с использованием пакетного файла с именем sync.sh
также не работает.
в инкронтабе:
/var/www/html/test IN_MODIFY,IN_ATTRIB,IN_CREATE /root/sync.sh
И в sync.sh
:
#!/bin/bash
touch /root/test
/usr/bin/unison -batch /var/www/html/test ssh://host-2//var/www/html/test
Опять же, /root/test
все отлично обрабатывается, то есть inofify отлично работает каждый раз, когда я обновляю файл в /var/www/html/test
, но снова нет никакого результата от unison
.
/var/log/cron выглядит так:
May 21 06:33:44 Host-1 incrond[28339]: (root) CMD (sh /root/sync.sh)
и unison.log
вообще не обновляется.
Выводы:
inotify
работает отлично, обнаруживает все изменения в файловой системе и выполняет задачу, за исключением любойunison
задачи.unison
отлично работает из командной строки и в пакетном режиме, за исключением случаев, когда вызывается демономincrond
.
Я что-то упускаю из виду?
решение1
Чтобы установить SSH-соединение, клиент должен пройти аутентификацию на сервере. Вероятно, вы используете аутентификацию на основе ключей, с ключом, хранящимся в защищенном паролем файле и загруженным в SSH-агент. SSH-клиент знает, как найти агента через переменную окружения SSH_AUTH_SOCK
. В задании cron или incron окружение отличается от вашего интерактивного сеанса, оно довольно минимальное, без SSH_AUTH_SOCK
, поэтому SSH-клиент не может подключиться к удаленной машине.
Если SSH-соединение установить не удается, Unison даже не начинает искать файлы для синхронизации и ничего не записывается unison.log
.
В стандартной ошибке скрипта есть сообщения об ошибках, но вы их нигде не регистрируете. Добавьте что-то вроде exec 2>&1 >>~/.unison-sync.log; date
в начало вашего скрипта.
Чтобы SSH-соединение заработало, вам нужно либо организовать доступ задания Unison к вашему агенту, либо настроить ключ без пароля. Если вы хотите пройти через своего агента, см.Невозможно подключиться по ssh к удаленной машине с помощью скрипта оболочки в Crontab; но тогда это будет работать только пока вы вошли в систему. Если вы хотите, чтобы синхронизация работала все время, единственным решением будет ключ без пароля. Поскольку вы используете Unison и, следовательно, SSH как root, закрытый ключ должен быть в /root/.ssh
, а не в вашей учетной записи. То же самое касается любой соответствующей опции в .ssh/config
. На стороне сервера вы можете авторизовать открытый ключ только для запуска определенной команды unison с помощью command=…
директивы в .ssh/authorized_keys
(см.Создание учетной записи UNIX, которая выполняет только одну команду(например). При ограничении команд, если кто-то получит доступ к локальной учетной записи root, он сможет выполнить только эту конкретную unison …
команду на host-2
; я не знаю, можно ли обманом заставить Unison выполнить произвольный код таким образом.