У меня есть запланированный сценарий, который ежечасно выполняет svnsync-резервное копирование наших репозиториев Subversion. Я без проблем запускал его из записи в корневом crontab, но решил, что хочу запускать его из /etc/cron.hourly вместо этого для дополнительной видимости (и потому что один из наших инженеров случайно удалил crontab, потому что он подумал, что «crontab -r "означало" прочитать crontab ;-))
Команды svnsync в скрипте cron.hourly завершаются сбоем с сообщением о том, что необходимо принять сертификат SSL для репозитория SVN (это сообщение вы получаете в интерактивном режиме при первом доступе пользователя к репозиторию SVN, но как только сертификат I принял, сообщение больше не появляется).
Поэтому мне кажется, что скрипт выполняется в другой пользовательской среде при запуске из cron.hourly, чем при запуске через корневой crontab. Кто-нибудь может объяснить разницу?
ОБНОВЛЕНИЕ: я должен был упомянуть свой дистрибутив, я использую anacron на CentOS 5.1.
ОБНОВЛЕНИЕ 2: Спасибо за предложения; Я думаю, что это больше похоже на вопрос о Subversion. Я всегда пытаюсь инкапсулировать свою среду в свои сценарии, но проблема здесь в том, что я не уверен, что именно в среде (или ее не хватает) заставляет SVN запрашивать принятие сертификата SSL, когда я запускаю свой сценарий из cron.hourly. Я предполагаю, что это как-то связано со способом выполнения скрипта run-parts.
В системе Debian / Ubuntu cron.daily | weekly | montly запускаются из основного crontab.
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
Также имейте в виду, что вы, вероятно, можете разместить фрагмент crontab в /etc/cron.d/
Как видите, в этой среде нет ничего особенного. По крайней мере, в Debian / Ubuntu все это запускается под учетной записью root.
Когда я пишу сценарии cron в самом начале сценария, я всегда устанавливаю свой PATH и другие переменные среды, которые я буду использовать, поэтому я могу быть уверен, что он будет работать правильно в любой среде.
Обычный общесистемный crontab - это crontab конкретного пользователя, и в нем есть поле имени пользователя, используемое /etc/crontab
.
Использование скриптов в /etc/cron.*
(ежечасно, ежедневно, еженедельно, ежемесячно) - более чистый и простой способ (предотвращает распространенные синтаксические ошибки) настройки crontab для root
пользователь, и этим занимается run-parts
которые запускают сценарии или программы в каталоге. Все эти правила по-прежнему определены в общесистемном crontab (/etc/crontab
), так что это одно и то же.
Когда задания cron обрабатываются run-parts
, легче отлаживать, так как вы можете просто проверить, какие скрипты будут запускаться (еще не выполняя их):
sudo run-parts --report --test /etc/cron.daily
Вы хотите использовать параметр --config-dir, чтобы сообщить ему, где найти принятый сертификат (например, ~ / .subversion по умолчанию).
Тем не менее, я почти уверен, что вам лучше вместо этого вызвать svnsync из сценария хуков / пост-фиксации, поскольку предложено в другом месте. Тогда ваше зеркало всегда синхронизировано, а не синхронизировано с тем местом, где был ваш хозяин час назад.
Моей первой безумной догадкой было бы проверить вашу переменную HOME.
В моей системе Centos crontab man 5 говорит:
Некоторые переменные среды устанавливаются автоматически демоном cron (8). SHELL установлен в / bin / sh, а LOGNAME и HOME устанавливаются из строки / etc / passwd владельца crontab.
Итак, если вы не указали иное, root crontab будет использовать / root для HOME. Но в / etc / crontab (откуда запускается /etc/cron.hourly через run-parts) HOME установлен в / (а SHELL в / bin / bash вместо / bin / sh).
Я не знаю о svnsync, но Subversion действительно использует каталог ˜ / .subversion /, так что это может зависеть от HOME.
В моей системе RHEL 5.1 переменная среды PATH устанавливается из / etc / crontab. Все, что находится наверху, - это то, что попадает в окружающую среду.
Если перезапустить cron, то при первом запуске (если из /etc/crontab
или /var/spool/cron/$USER
) он запишет это в / var / log / cron. В противном случае он просто отметит, что cron.hourly запущен
Мой crontab настроен на следующее:
01 * * * * root run-parts /etc/cron.hourly
02 4 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly
Что вы можете сделать, так это поместить в /etc/cron.hourly что-то вроде следующего:
env > /tmp/cron.env
Затем проверьте файл, когда он появится, и либо измените свой сценарий (если можете), чтобы правильно настроить среду, либо напишите короткий сценарий оболочки, который будет вызывать ваш crontab.
/var/log/messages
(или эквивалент в вашем дистрибутиве) должен сообщить вам особенности того, какая команда была запущена, когда и от имени какого пользователя.
Никогда не предполагайте, что в окружающей среде что-то есть. Всегда используйте защитный код. У вас есть целый файл, чтобы поместить туда любую настройку среды, которую вы хотите. Используй это.
Немногое о переносимости, в последний раз, когда я проверял (в Debian), было рекомендовано помещать материал в cron.hourly (и другие), а не непосредственно в crontab, если вы хотите создать пакет со своими материалами.