Как правильно настроить работу cron

36

Я попытался настроить задание root cron для запуска скрипта Bash от имени root, чтобы он выполнялся с минутой 7, 37, каждый час, каждый день месяца, каждый месяц. Этот скрипт находится в /usr/binи назван tunlrupdate.sh. Обновляет DNS Tunlr.

$ ls -l /usr/bin/tunlrupdate.sh 
-rwxr-xr-x 1 root root 2133 Sep 24 15:42 /usr/bin/tunlrupdate.sh

Этот скрипт Bash доступен здесь .

При запуске сценарий пишет, что происходит в журнале, расположенном в /var/log/tunlr.log

Чтобы добавить это задание root cron, я использовал стандарт crontab для root

sudo crontab -e

И вставил эти 2 строки в конце. Я ожидаю, что cron запустит скрипт от имени пользователя root.

# check for updated Tunlr DNS every 30 minutes at the hour + 7 mn and hour + 37 mn
07,37 * * * * root /usr/bin/tunlrupdate.sh

Более поздняя команда sudo crontab -lподтвердила, что задание cron было вставлено.

Я перезагрузил Ubuntu и проверял в файле журнала, правильно ли запущено задание cron. Однако в лог-файле ничего нет, что /var/log/tunlr.logозначает, что задание никогда не запускалось успешно.

Я проверял, что если я запускаю скрипт из командной строки

sudo /usr/bin/tunlrupdate.sh

тогда файл журнала обновляется соответственно.

Почему эта работа cron не выполняется, как запланировано, в моей системе?

ОБНОВЛЕНИЕ 1: Все предложенные решения пока не работают. Я благодарю Олли за CLI, чтобы перечислить системный журнал sudo grep CRON /var/log/syslog. Однако я получил ошибку CRON

CRON[13092]: (root) CMD (  [ -x /usr/lib/php5/maxlifetime ] && [ -d /var/lib/php5 ]
&& find /var/lib/php5/ -depth -mindepth 1 -maxdepth 1 -type f -cmin +$(/usr/lib/php
/maxlifetime) ! -execdir fuser -s {} 2>/dev/null \; -delete)

с предложенным PATH = вставка и использование абсолютного пути от корня для функций в сценарии или без предлагаемых здесь решений. Я все еще получаю эту ошибку.

После некоторого поиска я обнаружил ошибку в файле, /usr/lib/php5/maxlifetimeкак описано здесь :Change #!/bin/sh -e --> #!/bin/sh -x

Затем перечисление журнала ошибок CRON в моей системе

sudo grep CRON /var/log/syslog
Feb 11 18:07:01 Marius-PC CRON[14067]: (root) CMD (root /usr/bin/tunlrupdate.sh)
Feb 11 18:07:01 Marius-PC CRON[14066]: (root) MAIL (mailed 1 byte of output; but got
status 0x00ff, #012)

Я до сих пор не могу выполнить скрипт bash. На этот раз ошибка не отображается в журнале. Чтобы получить уверенность, что это не было содержанием сценария, я сократил сценарий до следующих 3 строк:

#!/bin/bash
LOGFILE=/var/log/tunlr.log
echo $LOGFILE >> $LOGFILE

Я до сих пор не справляюсь с работой cron. Ничего не написано в файле журнала. Так может даже пустой скрипт не запустится в cron? Я не понимаю Я знаю, пытаясь сценарий сводится к этим 2 строкам:

#!/bin/bash
exit 0

И все тот же журнал ошибок. Сценарий cron не проходит ...

Антонио
источник
Если вы хотите, чтобы он был «корневым» cronjob, вы должны быть пользователем root, тогда вы вводите crontab -e. Также вам нужно просто войти в систему как root (консольный тип "su root"), а затем crontab -e (в этом случае sudo не требуется).
Вольфганг
Что ж. Я не вижу смысла вашего ответа? Набрав $ sudo crontab -e, вы выполнили задание, о котором сообщает $ sudo crontab -l, то есть строка, описывающая новое задание, была добавлена ​​в cron root. Само по себе задание отсутствует в пользовательском cron, например, $ crontab -l не показывает, что здесь добавлено задание cron.
Антонио
@WolfgangVogl он использовал "sudo", который работает как ожидалось.
Алексис Уилке

Ответы:

68

Если вы хотите запустить скрипт как обычный пользователь :

crontab -e

И добавьте строку:

07,37 * * * * /usr/bin/tunlrupdate.sh

Если вы хотите запустить свой скрипт от имени пользователя root :

sudo crontab -e

И добавьте ту же строку:

07,37 * * * * /usr/bin/tunlrupdate.sh
Гийом
источник
@NineCattoRules Если вы не отбрасываете вывод, что вы видите?
Анджело Фукс,
@AngeloFuchs старый комментарий ... конечно, я пробовал эту команду от имени пользователя root ( sudo crontab -eвместо crontab -e). Или что-то еще, в любом случае это работает
NineCattoRules
10

Ну наконец то рабочее решение. В системном журнале я видел повторяющиеся и интригующие:

CRON[18770]: (root) CMD (root /usr/bin/tunlrupdate.sh)

Похоже, что root не был распознан как cmd. Как я уже использовал cron рута с помощью $ sudo /usr/bin/tunlrupdate.sh. Затем я попытался с оригинальным сценарием (исправленным для ошибки в дате UNIX cmd:% m, который является месяцем, использованным для минут, который является% M), следующее (которое удаляет корень из строки cron):

$ sudo crontab -e
# check for updated Tunlr DNS every 30 minutes at the hour + 7 mn and hour + 37 mn
07,37 * * * * /usr/bin/tunlrupdate.sh

Это оказалось окончательным решением. [Хотя я нашел множество литературных источников, в которых указана ошибочная строка с корнем в строке cron. Это была ошибка].

Антонио
источник
Хороший вопрос, Олли. Я согласен с вами в этом. Для справки пользователь crontab хранится в / var / spool / cron / crontabs / user-name или для root / var / spool / cron / crontabs / root. См. Эту страницу. Askubuntu.com/questions/216692/where-is-the-user-crontab-stored Папка с данными уже есть и дает имя пользователя.
Антонио
Ну, вам не нужна эта информация, так как вы должны редактировать файлы crontab только с помощью crontabкоманды (кроме файлов crontab в /etc).
Олли
1
@ Антонио баллы с полем имени пользователя используются только в /etc/crontab(общесистемный crontab). Используя sudo crontab -eвы работаете с crontab root, который обычно можно найти в/var/spool/cron/crontabs
Matijs
2

Одна из «проблем» cron - отсутствие переменных окружения (по понятным причинам безопасности). Возможно, вам не хватает PATH и HOME. Вы можете определить их в скрипте напрямую или в файле crontab.

# check for updated Tunlr DNS every 30 minutes at the hour + 7 mn and hour + 37 mn
PATH=/usr/bin
07,37 * * * * root /usr/bin/tunlrupdate.sh

Вам придется тестировать, пока все необходимые переменные не будут определены в соответствии с требованиями сценария.

Алексис Уилке
источник
1
Это единственный ответ, который действительно сработал для меня. Я скопировал из /etc/crontabфайла операторы SHELL и PATH и вставил их в команду, sudo crontab -eи команда без проблем запустилась с правами root. Спасибо!
Терренс
0

Сообщения об ошибках Cron обычно - по умолчанию - отправляются по электронной почте. Вы можете проверить, есть ли электронная почта для пользователя root sudo mail, или просто проверить содержимое /var/mail/root, например sudo less /var/mail/root.


Если сообщения электронной почты не помогают, также проверьте /var/log/syslog:

sudo grep CRON /var/log/syslog

Как уже сказал Алексис Вилке, у cron есть другой механизм установки переменных окружения.

Ваш сценарий нуждается

PATH=/sbin:/bin:/usr/bin

в хронтаб. HOMEне должно быть необходимым. Вы должны использовать абсолютные пути в ваших скриптах, например, /bin/dateвместо date. Вы можете найти правильные пути для каждой команды which command_name, например,

$ which date
/bin/date
Олли
источник
Запустив предложенный вами grep CRON в / var / log / syslog, я получил сообщение от 11 февраля 14:37:01 Marius-PC CRON [7826]: (root) CMD (root /usr/bin/tunlrupdate.sh) 11 февраля 14: 37:01 CRUS Marius-PC [7825]: (root) MAIL (отправлено по почте 1 байт, но получено состояние 0x00ff, # 012) 11 февраля 14:39:01 CRON Marius-PC [7849]: (root) CMD ( [-x / usr / lib / php5 / maxlifetime] && [-d / var / lib / php5] && find / var / lib / php5 / -depth -mindepth 1 -maxdepth 1 -тип f -cmin + $ (/ usr / lib / php5 / maxlifetime)! -execdir fuser -s {} 2> / dev / null \; -delete) Если я добавлю некоторые определения для PATH в cron, это не повлияет на мою систему $ PATH?
Антонио
Этот вывод говорит, что он пытался что-то отправить по электронной почте, но не смог. Это означает, что вы не получаете это сообщение об ошибке /var/mail/root. Вы можете либо исправить это, либо попробоватьPATH=...
Olli
@Antonio, альтернативно, используйте эту исправленную версию
Olli
Спасибо. Я знаю, что не настраивал системную электронную почту и знал, что не прошел. Я уже модифицировал скрипт для использования абсолютного пути для любой вызываемой функции. Последним был мой предыдущий вопрос: определение PATH в crontab не испортит мою системную переменную $ PATH?
Антонио
1
В то же время я был занят исправлением ошибки в формате даты из оригинального сценария. Он использовал% m (то есть в течение месяца, а не минуты) вместо% M ...
Антонио
0

Вы можете добавить эту строку в свой скрипт. Таким образом, после того, как вы проверите журналы cron и подтвердите, что ваша работа была выполнена, вы можете получить тот же $ PATH crontabs.

/bin/echo $PATH > /root/path.txt

И, вероятно, лучшее, что вы можете сделать для диагностики проблем в скриптах cron - это получить все переменные окружения SO с помощью команды env в вашем скрипте. Так что просто добавьте эту строку в ваш скрипт. Затем вы можете проанализировать выводallEvnVars.txt

/usr/bin/env > /root/allEvnVars.txt

Другой трюк - направить вывод сценария в какое-то место. Добавление /root/log.log. Таким образом, весь вывод скрипта будет сохранен в/root/log.log

07,37 * * * * root /usr/bin/tunlrupdate.sh  > /root/log.log

Также вы можете запланировать запуск скрипта каждую минуту, чтобы облегчить тесты и проверки.

*/1 * * * * root /usr/bin/tunlrupdate.sh  > /root/log.log
Кассио Сеффрин
источник