У меня есть сценарий 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
регистрирует начало каждого задания (см. man cron
). Например, если вы запускаете демон Vixie cron, это можно сделать, указав параметр -L 1
вариант (или -L 2
если вы также хотите проверить, когда ваша работа закончится).где питон
вывод должен быть ...
/ 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 может быть не в состоянии делать то, что вы просите, потому что разрешения этого не позволяют.