CronJob не работает
У меня есть настройка cronjob для пользователя root в среде ubuntu следующим образом, набрав crontab -e
34 11 * * * sh /srv/www/live/CronJobs/daily.sh
0 08 * * 2 sh /srv/www/live/CronJobs/weekly.sh
0 08 1 * * sh /srv/www/live/CronJobs/monthly.sh
Но cronjon не запускается. Я попытался проверить, работает ли cronjob с помощью
pgrep cron
и это дает идентификатор процесса 3033. Сценарий оболочки вызывает python файл и используется для отправки электронной почты. Запуск файла python в порядке. Там нет ошибок, но cron не запускается. Файл daily.sh имеет в нем следующий код.
python /srv/www/live/CronJobs/daily.py
python /srv/www/live/CronJobs/notification_email.py
python /srv/www/live/CronJobs/log_kpi.py
Ответы
Ответ 1
WTF?! Мой cronjob не работает?!
Вот руководство по контрольному списку для отладки не работающих cronjobs:
- Работает ли демон Cron?
- Запустите
ps ax | grep cron
и найдите cron.
- Debian:
service cron start
или service cron restart
- Cron работает?
* * * * * /bin/echo "cron works" >> /tmp/file
- Синтаксис правильный? Смотрите ниже.
- Вам, очевидно, нужно иметь доступ на запись к файлу, на который вы перенаправляете вывод. Уникальное имя файла в
/tmp
, которое в настоящее время не существует, всегда должно быть доступно для записи.
- Команда работает автономно?
- Проверьте, есть ли в скрипте ошибка, выполнив пробный запуск на CLI
- тестируя вашу команду, проверьте, что пользователь, чей crontab вы редактируете, может не быть вашим логином или root
- Может ли Cron управлять вашей работой?
- Проверьте
/var/log/cron.log
или /var/log/messages
на наличие ошибок.
- Ubuntu:
grep CRON /var/log/syslog
- Redhat:
/var/log/cron
- Проверьте разрешения
- установить исполняемый флаг в команде:
chmod +x /var/www/app/cron/do-stuff.php
- если вы перенаправили вывод своей команды в файл, убедитесь, что у вас есть разрешение на запись в этот файл/каталог
- Проверьте пути
- проверить линию чел-хэнг-бэнгс
- не полагайтесь на переменные окружения, такие как PATH, поскольку их значение в cron, скорее всего, не будет таким же, как в интерактивном сеансе
- Не подавлять вывод во время отладки
- обычно используется это подавление:
30 1 * * * command > /dev/null 2>&1
- повторно включите стандартный вывод или вывод стандартного сообщения об ошибке, удалив
>/dev/null 2>&1
полностью; или, возможно, перенаправить в файл в месте, где у вас есть доступ для записи: >>cron.out 2>&1
добавит стандартный вывод и стандартную ошибку к cron.out
в домашнем каталоге вызывающего пользователя.
Все еще не работает? Хлоп!
- Поднимите уровень отладки cron
- Debian
- в
/etc/default/cron
- установить
EXTRA_OPTS="-L 2"
service cron restart
tail -f /var/log/syslog
чтобы увидеть выполненные сценарии
- Ubuntu
- в
/etc/rsyslog.d/50-default.conf
- добавить или закомментировать строку
cron.crit /var/log/cron.log
- перезагрузить регистратор
sudo /etc/init.d/rsyslog reload
- повторно запустите cron
- откройте
/var/log/cron.log
и найдите подробный вывод ошибок
- Напоминание: отключите уровень журнала, когда вы закончите с отладкой
- Запустите cron и снова проверьте файлы журналов
Синтаксис Cronjob
# Minute Hour Day of Month Month Day of Week User Command
# (0-59) (0-23) (1-31) (1-12 or Jan-Dec) (0-6 or Sun-Sat)
0 2 * * * root /usr/bin/find
Этот синтаксис только правильный для пользователя root
. Синтаксис обычного пользователя crontab
не имеет поля Пользователь (обычные пользователи не могут запускать код как любой другой пользователь);
# Minute Hour Day of Month Month Day of Week Command
# (0-59) (0-23) (1-31) (1-12 or Jan-Dec) (0-6 or Sun-Sat)
0 2 * * * /usr/bin/find
Команды Crontab
crontab -l
- Перечисляет все пользовательские задачи cron.
crontab -e
, для конкретного пользователя: crontab -e -u agentsmith
- Запускает сеанс редактирования файла crontab.
- При выходе из редактора измененный crontab устанавливается автоматически.
crontab -r
- Удаляет вашу запись в crontab из спулера cron, но не из файла crontab.
Ответ 2
Наконец, я нашел решение. Ниже приведено решение: -
-
Никогда не используйте относительный путь в сценариях python для выполнения через crontab.
Я сделал что-то вроде этого: -
import os
import sys
import time, datetime
CLASS_PATH = '/srv/www/live/mainapp/classes'
SETTINGS_PATH = '/srv/www/live/foodtrade'
sys.path.insert(0, CLASS_PATH)
sys.path.insert(1,SETTINGS_PATH)
import other_py_files
-
Никогда не подавайте код crontab вместо почтового сервера и проверяйте почту для пользователя. Это дает более четкое представление о том, что происходит.
Ответ 3
Другая причина сбоя crontab: специальная обработка символа %
.
Из файла man:
The entire command portion of the line, up to a newline or a
"%" character, will be executed by /bin/sh or by the shell specified
in the SHELL variable of the cronfile. A "%" character in the
command, unless escaped with a backslash (\), will be changed into
newline characters, and all data after the first % will be sent to
the command as standard input.
В моем конкретном случае я использовал date --date="7 days ago" "+%Y-%m-%d"
для создания параметров для моего сценария, и он молча давал сбой. Наконец, я узнал, что происходит, когда проверил syslog
и увидел, что моя команда была усечена до символа %
. Вы должны избежать этого следующим образом:
date --date="7 days ago" "+\%Y-\%m-\%d"
Смотрите здесь для более подробной информации:
http://www.ducea.com/2008/11/12/using-the-character-in-crontab-entries/
Ответ 4
Я хочу добавить 2 очка, которые я узнал:
- Файлы конфигурации Cron, помещенные в /etc/cron.d/, не должны содержать точку (.). В противном случае он не будет считаться cron.
- Если пользователь, выполняющий вашу команду, не находится в /etc/shadow. Не разрешено планировать cron.
Refs:
Ответ 5
Я нашел еще одну причину, по которой пользователь crontab не работает: имя хоста отсутствует в файле hosts:
[email protected]:~$ cat /etc/hostname
ubuntu
Теперь файл hosts:
[email protected]:~$ cat /etc/hosts
127.0.0.1 localhost
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
Это на Ubuntu 14.04.3 LTS, способ исправить это добавить имя хоста в файл hosts, чтобы он напоминал что-то вроде этого:
[email protected]:~$ cat /etc/hosts
127.0.0.1 ubuntu localhost
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
Ответ 6
Для меня решение заключалось в том, что файл cron пытался запустить, был в зашифрованном каталоге, более конкретно, в директории user/home/. Хотя crontab был настроен как root, поскольку запуск script, который был запущен в зашифрованном каталоге пользователя в /home/cron, мог читать этот каталог только в том случае, если пользователь был фактически зарегистрирован. Чтобы узнать, зашифрован ли каталог, проверьте, является ли этот каталог существует:
/home/.ecryptfs/<yourusername>
если это так, у вас есть зашифрованный домашний каталог.
Исправление для меня состояло в том, чтобы переместить script в не зашифрованный каталог, и каждый из них работал нормально.
Ответ 7
У меня возникла такая же проблема, когда кроны не работают.
Мы исправили изменение прав доступа и владельца
Хроны сделали владельца корня, как мы упоминали в crontab И
Предоставлено разрешение Cronjobs 644
Ответ 8
Иногда команда, которую должен выполнить cron, находится в каталоге, где cron не имеет доступа, как правило, в системах, где разрешения пользователей домашних каталогов - 700, а команда - в этом каталоге.