Как правильно настроить корневое задание cron

Я попытался настроить корневое задание 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 mn07,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)

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

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

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

sudo grep CRON /var/log/syslogFeb 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 gotstatus 0x00ff, #012)

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

#!/bin/bashLOGFILE=/var/log/tunlr.logecho $LOGFILE >> $LOGFILE

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

#!/bin/bashexit 0

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

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

crontab -e

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

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

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

sudo crontab -e

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

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

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

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

Похоже, root не был распознан как cmd. Поскольку я уже использовал cron root, используя $ 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 mn07,37 * * * * /usr/bin/tunlrupdate.sh

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

Одна "проблема" с cron заключается в том, что отсутствие переменных среды (для очевидный соображениям безопасности). Вероятно, вам не хватает ПУТИ и ДОМА. Вы можете определить их непосредственно в скрипте или в файле crontab.

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

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

Сообщения об ошибках 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

Вы можете добавить эту строку в свой скрипт. Таким образом, после того, как вы проверите журналы 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

Вы заявляете в своем вопросе, что сократили сценарий до:

#!/bin/bashLOGFILE=/var/log/tunlr.logecho $LOGFILE >> $LOGFILE

У меня и раньше были проблемы с этим. Это оказалась первая строка. Вместо #!/bin/bash Я пытался #!/bin/sh и это сработало (по крайней мере, для меня).

Если вы хотите, чтобы это был “корневой” cronjob, вы должны быть root, затем вы вводите crontab -e. Также вам просто нужно войти в систему как root (введите в консоли “su root”), а затем crontab -e (sudo в данном случае не требуется).

Хорошо. Я не вижу смысла в вашем ответе? Ввод $ sudo crontab -e выполнил задание, о котором сообщает $ sudo crontab -l , т.е. строка, описывающая новое задание, была добавлена в cron корневого каталога. Как таковое, задание отсутствует в пользовательском cron, например, $ crontab -l не показывает, что здесь было добавлено какое-либо задание cron.

@WolfgangVogl он использовал “sudo”, который работает, как и ожидалось.