Назад | Перейти на главную страницу

Работа Cron не выполняется тихо

У меня есть сценарий python, который я хочу запустить через crontab. Мой crontab выглядит так:

5,20,35,50 * * * * /var/www/django-apps/callreport/util.py

Этот сценарий настроен для анализа кучи плоских файлов и вставки информации в базу данных MySQL, а затем удаления файлов. Он отлично работает из командной строки, данные копируются в базу данных, а плоские файлы удаляются. Но ничего не происходит при запуске в качестве задания cron.

Раньше я получал почтовое сообщение, когда задание cron не удавалось, но я не получаю никакой обратной связи с этим, и я все еще чувствую свой путь, будучи системным администратором в этом поле. Что я делаю не так?

Обычная проблема с заданиями cron заключается в том, что у них нет среды - в отличие от заданий at, которые копируют вашу среду. Когда что-то работает из командной строки, а не из cron, мой опыт показывает, что «среда» является одной из наиболее распространенных проблем. Иногда вы сталкиваетесь с другой проблемой - задания cron не запускаются с помощью терминала, и иногда программы с этим не согласны. Однако это находится в диапазоне 1% по сравнению с 99% для проблем окружающей среды.

Другой ключевой прием, который я использую, - это всегда запускать сценарий оболочки из cron; сценарий оболочки гарантирует, что среда является установлен правильно, а затем запускает настоящую программу. Если задание cron вызывает у меня проблемы, я могу настроить скрипт, чтобы он делал такие полезные вещи, как это:

{
    date
    env | sort
    set -x
    ...what was there before adding the debug...
} >/tmp/cron.jobname.$$ 2>&1

Это перенаправляет весь вывод - стандартный вывод и стандартную ошибку - на имя файла. Вы можете встроить метки времени в имя файла, если предпочитаете это идентификатору процесса. Анализ файлов журнала часто быстро выявляет проблемы.

Сначала просто убедитесь, что crond запущен.

Когда cronjobs, которые работают в командной строке, не запускаются должным образом, это обычно проблема среды для меня - помните, что cronjob не будет работать как интерактивная оболочка.

Из командной строки запустите env (1) и скопируйте их куда-нибудь. Затем измените задание cron для запуска env, чтобы вы могли сравнить значения. Cron должен отправьте вам результат по электронной почте (вы сказали, что это было раньше); HD упомянул, как это настроить.

5,20,35,50 * * * * env; /var/www/django-apps/callreport/util.py

Вот несколько идей по устранению вашей проблемы:

  • Проверьте системные журналы, чтобы узнать, действительно ли демон cron запускает скрипт.
  • Если ваши задания не регистрируются, попробуйте увеличить уровень ведения журнала, чтобы cron регистрирует начало каждого задания (см. man cron). Например, если вы запускаете демон Vixie cron, это можно сделать, указав параметр -L 1 вариант (или -L 2 если вы также хотите проверить, когда ваша работа закончится).
  • Из вашего скрипта Python, как только он запустится, создайте пустой файл в каталоге / tmp (это еще один способ помочь вам убедиться, что скрипт вызывается cron и запускается без проблем)

где питон

вывод должен быть ...

/ usr / bin / питон

затем полный путь к python перед скриптом.

5,20,35,50 * * * * / usr / bin / python /var/www/django-apps/callreport/util.py

Я думаю, вы можете перенаправить вывод команды в файл, чтобы увидеть, почему он не работает, что-то вроде

/var/www/django-apps/callreport/util.py > /tmp/util_log.txt

большинство случаев, которые я видел для тихого сбоя, связаны с тем, что сценарий не может быть выполнен, а не проблема с самим сценарием

Вы можете поместить эту строку в начало вашего crontab:

MAILTO="user@domain.com"

Чтобы получать почту от cron. Также вы можете перенаправить вывод на временный сбой, как говорит Динеш Манн, чтобы проверить, что случилось с вашей командой. Просто спрашиваю: вы уверены, что используете того же пользователя, который запускает команду, и владельца редактируемого crontab?

Будьте абсолютно уверены, что ваш crond запускает скрипты с точкой в ​​имени файла ...!

Также - убедитесь, что вашего пользователя нет в cron.deny файл. Если ты только хочешь cron для запуска для определенных людей добавьте своего пользователя в cron.allow.

Заставьте его разбиться. Поместите что-нибудь не так вместо #! / Usr / bin / python и проверьте, получаете ли вы сообщение об ошибке по электронной почте - вы должны установить переменную MAILTO на свой адрес электронной почты. Но сначала проверьте, действительно ли скрипт не работает, если вы запускали его из командной строки. Если вы по-прежнему не получаете сообщение об ошибке электронной почты, проверьте, не застряли ли некоторые электронные письма в локальной очереди почты (mailq). Возможно, это поможет разобраться в тихом провале.

Кроме того, от каких внутренних систем зависит этот сценарий? DNS, ldap / nis? Есть ли у него жестко заданные IP-адреса или имена хостов, которых больше не существует (например, хост mysql)? Можете ли вы соотнести время последнего успешного выполнения с последним изменением, внесенным в сценарий? Кто-то делал скрытное обновление до Python на вашем компьютере? У вас достаточно места на диске и индексов (df -i)?

У вас есть пустая строка в конце файла crontab? Если вы заставляете скрипт запускаться от имени root (плохо, используйте его только для тестирования), он работает?

У вас есть эта работа в crontab пользователя (вы можете увидеть ее с помощью crontab -l?) или это в системном crontab (/etc/crontab)? Системный crontab (по крайней мере, в Linux не знает о других системах) требует дополнительного аргумента пользователя, которого нет в пользовательских crontab.

В пользовательском crontab это должно выглядеть так:

# crontab -l
...
5,20,35,50 * * * * /var/www/django-apps/callreport/util.py

Тогда как эта же команда в системном crontab должна выглядеть так:

# cat /etc/crontab
...
5,20,35,50 * * * * www-data /var/www/django-apps/callreport/util.py

Конечно, в вашей системе пользователь может быть другим, но это общая идея.

Похоже, вы уже проверили, но дважды проверьте, запускается ли скрипт от имени правильного пользователя. Когда я устраняю проблемы с заданиями cron, мне нравится использовать (на моем Mac) системные вызовы, используя say так, чтобы я слышал интересующие меня параметры. Поэтому я мог бы добавить util.py последующий:

import os
os.system('whoami')

Кроме этого, я бы вложил деньги в вопрос разрешения; ваша работа cron может быть не в состоянии делать то, что вы просите, потому что разрешения этого не позволяют.