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
Но Кронджон не бежит. Я попытался проверить, работает ли cronjob, используя
пгреп крон
и это дает идентификатор процесса 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
20 ответов
WTF?! Мой cronjob не работает?!
Вот контрольный список руководства по отладке не запущенных cronjobs:
- Работает ли демон Cron?
- Бежать
ps ax | grep 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
- Красная шляпа:
/var/log/cron
- Проверьте
- Проверьте разрешения
- установить исполняемый флаг в команде:
chmod +x /var/www/app/cron/do-stuff.php
- если вы перенаправите вывод вашей команды в файл, убедитесь, что у вас есть разрешение на запись в этот файл / каталог
- установить исполняемый флаг в команде:
- Проверьте пути
- проверить линию чел-хэнг-бэнгс
- не полагайтесь на переменные окружения, такие как PATH, поскольку их значение в cron, скорее всего, будет не таким, как в интерактивном сеансе
- Не подавлять вывод во время отладки
- обычно используется это подавление:
30 1 * * * command > /dev/null 2>&1
- повторно включить стандартный вывод или стандартный вывод сообщения об ошибке
- обычно используется это подавление:
До сих пор не работает? Хлоп!
- Поднимите уровень отладки 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
и искать подробный вывод ошибок
- в
- Напоминание: отключите уровень журнала, когда вы закончите с отладкой
- Debian
- Запустите 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
синтаксис не имеет поля User (обычные пользователи не могут запускать код как любой другой пользователь);
# 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.
Еще одна причина, по которой 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/
Наконец я нашел решение. Ниже приводится решение:-
Никогда не используйте относительный путь в скриптах 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, вместо этого используйте mailserver и проверяйте почту для пользователя. Это дает более четкое представление о том, что происходит.
Я хочу добавить 2 пункта, которые я узнал:
- Конфигурационные файлы Cron, помещенные в /etc/cron.d/, не должны содержать точку (.). В противном случае он не будет прочитан cron.
- Если пользователь, выполняющий вашу команду, не находится в / etc / shadow. Не будет разрешено планировать cron.
Refs:
Чтобы добавить еще одну точку, файл в /etc/cron.d должен содержать в конце пустую новую строку. Вероятно, это связано с ответом Лучано, который указывает, что:
The entire command portion of the line, up to a newline or a "%"
character, will be executed
Это также может быть проблема с часовым поясом.
Cron использует местное время.
Запустите команду
timedatectl
чтобы увидеть машинное время и убедиться, что ваш crontab находится в том же часовом поясе.
Поскольку это становится каноническим для устранения неполадок, позвольте мне добавить одну конкретную и довольно сложную проблему: если вы пытаетесь запустить программу с графическим интерфейсом, вероятно, вы делаете это неправильно.
Распространенным признаком является получение сообщений об ошибках о
DISPLAY
не установлен, или процесс задания не может получить доступ к дисплею.
Вкратце, это означает, что программа, которую вы пытаетесь запустить, пытается отобразить что-то на дисплее X11 (или Wayland и т. Д.) И терпит неудачу, потому что не привязана к графической среде или, фактически, к любому типу средства ввода / вывода. вообще, помимо возможности читать и записывать файлы и отправлять электронную почту, если система настроена таким образом.
Для целей «Я не могу выполнить свою работу», давайте просто обозначим в общих чертах три распространенных сценария этой проблемы. Вероятно, определите случай, который вы пытаетесь реализовать, и выполните поиск связанных вопросов об этом конкретном сценарии, чтобы узнать больше и найти реальные решения с реальным кодом.
Если вы пытаетесь запустить интерактивную программу, которая общается с пользователем, вы хотите переосмыслить свой подход. Распространенным, но нетривиальным решением является разделение программы на две части: внутренняя служба, которая может запускаться, но не имеет каких-либо видимых для пользователя интерактивных средств, и интерфейсный клиент, который пользователь запускает из своего графического интерфейса. когда они хотят общаться с серверной службой.
Вероятно, ваш пользовательский клиент должен быть просто добавлен в сценарий запуска графического интерфейса пользователя (ов), если он должен быть или они хотят, чтобы он запускался автоматически при входе в систему.
Внутреннюю службу вполне можно запустить из, хотя, если для ее использования требуется графический интерфейс, можно вместо этого запустить ее из сценариев запуска сервера X11.
Если вы пытаетесь запустить программу с графическим интерфейсом без взаимодействия с реальным пользователем 1 , вы можете настроить «безголовый» сервер X11 2 и запустить задание, которое запускает этот сервер, выполняет ваше задание и завершает работу.
Вероятно, ваша работа должна просто запустить подходящий X-сервер и передать ему конфигурацию, которая запускает клиента (-ы), который вы хотите запустить, после того, как он будет запущен.
Вы используете компьютер с единственной целью - отобразить конкретное приложение в графическом интерфейсе пользователя, и вы хотите запустить это приложение из.
Вероятно, ваши сценарии запуска должны просто запускать графический интерфейс (X11 или что-то еще) и подключаться к его сценарию запуска, чтобы также запустить клиентскую программу, как только графический интерфейс будет запущен и запущен. Другими словами, вам здесь не нужно; просто настройте сценарии запуска для запуска графического интерфейса рабочего стола и настройте графический интерфейс рабочего стола для запуска вашего приложения как части (предположительно автоматической, гостевой?) последовательности входа в систему.
Там являются способы для запуска программ Х11 на основном дисплее системы (
DISPLAY=:0.0
), но сделать это из задания часто проблематично, поскольку этот дисплей обычно резервируется для реального интерактивного пользователя первым пользователем, который входит в систему и запускает графический рабочий стол. В однопользовательской системе вы можете смириться с последствиями, если этот пользователь также является вами, но это, как правило, имеет неудобные последствия и очень плохо масштабируется.
Дополнительная сложность заключается в том, чтобы решить, какого пользователя запускать
cron
работа как. Общий системный ресурс, такой как серверная служба, может и, вероятно, должен запускаться (хотя в идеале иметь выделенную учетную запись пользователя, на которую он переключается после получения доступа к любым привилегированным ресурсам, которые ему нужны), но все, что запускает графический интерфейс, определенно не должно беги как
root
в любой момент.
В качестве дополнительного дополнения: на выделенных серверах (услуги веб-хостинга, суперкомпьютерные кластеры и т. Д.) Вы можете даже нарушить условия обслуживания хостинговой компании или учреждения, если вы установите интерактивный графический рабочий стол, к которому вы можете подключиться из внешнего мира.
1 Распространенным случаем является запуск веб-браузера, который должен запускать полноценный клиент с графическим интерфейсом пользователя, но который управляется программно и которому на самом деле не нужно ничего нигде отображать. Другой - плохо спроектированное научное программное обеспечение, которое не было написано для пакетного использования, и поэтому требует графического интерфейса, даже если вы просто хотите запустить пакетное задание, а затем немедленно выйти без какой-либо реальной необходимости что-либо отображать где-либо.
2
Xvfb
является стандартным де-факто решением; он запускает «виртуальный кадровый буфер», в котором компьютер может выводить пиксели, как если бы на дисплей, но который на самом деле не подключен к какому-либо дисплейному оборудованию.
Я нашел полезную информацию об отладке на сервере Ubuntu 16.04, выполнив:
systemctl status cron.service
В моем случае мне любезно сообщили, что я оставил комментарий '#' вне строки примечания:
Aug 18 19:12:01 is-feb19 cron[14307]: Error: bad minute; while reading /etc/crontab
Aug 18 19:12:01 is-feb19 cron[14307]: (*system*) ERROR (Syntax error, this crontab file will be ignored)
MTA не установлен, выходные данные отбрасываются
У меня была аналогичная проблема с файлом PHP, выполняемым как задание CRON. Когда я вручную запускаю файл, он работает, но не с вкладкой CRON.
Я получил выходное сообщение: «MTA не установлен, вывод отбрасывается» .
Postfix является агентом передачи почты (MTA) по умолчанию в Ubuntu и может быть установлен с помощью
sudo apt-get install postfix
Но это же сообщение может быть выведено, когда вы добавляете файл журнала, как показано ниже, и у него нет надлежащего разрешения на запись в /path/to/logfile.log.
/path/to/php -f /path/to/script.php >> /path/to/logfile.log
Проблема с разрешением может возникнуть, если вы создадите файл cron-log вручную с помощью такой команды, как
Чтобы предотвратить это:
- Создайте файл с надлежащим разрешением.
- Избегайте создания соответствующего файла журнала CRON вручную, добавьте журнал на вкладке CRON и позвольте файлу журнала создаваться автоматически при запуске cron.
У меня была проблема, похожая на ссылку ниже.
похоже на мою проблему,
мой исходный пост
Моя проблема
Моя проблема заключалась в том, что cron / crontab не выполнял мой сценарий bash. этот сценарий bash выполнил сценарий python.
исходный файл bash
#!/bin/bash
python /home/frosty/code/test_scripts/test.py
файл python (test.py)
from datetime import datetime
def main():
dt_now = datetime.now()
string_now = dt_now.strftime('%Y-%m-%d %H:%M:%S.%f')
with open('./text_file.txt', 'a') as f:
f.write(f'wrote at {string_now}\n')
return None
if __name__ == '__main__':
main()
ошибка, которую я получал
File "/home/frosty/code/test_scripts/test.py", line 7
string_to_write = f'wrote at {string_now}\n'
^
SyntaxError: invalid syntax
эта ошибка не имела смысла, потому что код выполнялся без ошибок из файла bash и файла python.
** Примечание -> убедитесь в
crontab -e
файл, вы не подавляете вывод. Я отправил результат в файл, добавив
>>/path/to/cron/output/file.log 2>&1
после команды. ниже моя запись crontab -e
*/5 * * * * /home/frosty/code/test_scripts/echo_message_sh >>/home/frosty/code/test_scripts/cron_out.log 2>&1
проблема
cron использовал неправильный интерпретатор python, вероятно, python 2 из-за синтаксической ошибки.
как я решил проблему
Я изменил свой файл bash на следующий
#!/bin/bash
conda_shell=/home/frosty/anaconda3/etc/profile.d/conda.sh
conda_env=base
source ${conda_shell}
conda activate ${conda_env}
python /home/frosty/code/test_scripts/test.py
И я изменил свой файл python на следующий
from datetime import datetime
def main():
dt_now = datetime.now()
string_now = dt_now.strftime('%Y-%m-%d %H:%M:%S.%f')
string_file = '/home/frosty/code/test_scripts/text_file.txt'
string_to_write = 'wrote at {}\n'.format(string_now)
with open(string_file, 'a') as f:
f.write(string_to_write)
return None
if __name__ == '__main__':
main()
Ответов уже много, но ни один из них мне не помог, поэтому я добавлю свой сюда на случай, если это будет полезно для кого-то еще.
В моей ситуации мои cronjobs работали, пока не возникла нехватка электроэнергии, которая отключила питание моего Raspberry Pi. Cron поврежден. Я думаю, что именно тогда, когда возникла нехватка, он запускал длинный скрипт Python. Ничего в основном ответе выше у меня не сработало. Однако решение было довольно простым. Мне просто пришлось принудительно переустановить cron с помощью:
sudo apt-get --reinstall install cron
Работает сразу после этого.
CRON использует другой TIMEZONE
Очень распространенная проблема: настройки времени cron могут отличаться от ваших. В частности, часовой пояс может быть другим:
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
Вы можете запустить:
* * * * * echo $(date) >> /tmp/test.txt
Это должно сгенерировать файл вида:
# cat test.txt
Sun 03 Apr 2022 09:02:01 AM UTC
Sun 03 Apr 2022 09:03:01 AM UTC
Sun 03 Apr 2022 09:04:01 AM UTC
Sun 03 Apr 2022 09:05:01 AM UTC
Sun 03 Apr 2022 09:06:01 AM UTC
Если вы используете TZ, отличный от UTC, вы можете попробовать:
timedatectl set-timezone America/Sao_Paulo
заменять
America/Sao_Paulo
в соответствии с вашими настройками.
Я не уверен, что это действительно необходимо, но вы можете запустить:
sudo systemctl restart cron.service
После этого cron работает так, как я и ожидал:
# cat test.txt
Sun 03 Apr 2022 09:02:01 AM UTC
Sun 03 Apr 2022 09:03:01 AM UTC
Sun 03 Apr 2022 09:04:01 AM UTC
Sun 03 Apr 2022 09:05:01 AM UTC
Sun 03 Apr 2022 09:06:01 AM UTC
Sun 03 Apr 2022 09:07:01 AM UTC
Sun 03 Apr 2022 09:08:01 AM UTC
Sun 03 Apr 2022 09:09:01 AM UTC
Sun 03 Apr 2022 09:10:01 AM UTC
Sun 03 Apr 2022 06:11:01 AM -03
Sun 03 Apr 2022 06:12:01 AM -03
Sun 03 Apr 2022 06:13:01 AM -03
Sun 03 Apr 2022 06:14:01 AM -03
Я нашел еще одну причину, по которой пользователь не запускает crontab: имя хоста отсутствует в файле hosts:
user@ubuntu:~$ cat /etc/hostname
ubuntu
Теперь файл hosts:
user@ubuntu:~$ 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, чтобы он выглядел примерно так:
user@ubuntu:~$ 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
Копирую мой ответ на дублированный вопрос здесь.
cron может не знать, где найти интерпретатор Python, потому что он не использует переменные среды вашей учетной записи.
Для этого есть 3 решения:
Если Python находится в
/usr/bin/python
, вы можете изменить задание cron, чтобы использовать абсолютный путь:/usr/bin/python /srv/www/live/CronJobs/daily.py
В качестве альтернативы вы также можете добавить значение PATH в crontab с помощью
PATH=/usr/bin
.Другое решение - указать интерпретатор в файле сценария, сделать его исполняемым и вызвать сам сценарий в вашем crontab:
а. Поместите shebang в начало файла python:
#!/usr/bin/python
.б. Установите его в исполняемый файл:
$ chmod +x /srv/www/live/CronJobs/daily.py
c. Поместите это в crontab:
/srv/www/live/CronJobs/daily.py
Измените путь к интерпретатору Python, если он отличается в вашей системе.
Для меня решение состояло в том, что файл, который пытался запустить cron, находился в зашифрованном каталоге, точнее, в директории пользователя в /home/. Хотя crontab был настроен как root, так как выполняемый скрипт находился в зашифрованном каталоге пользователя в /home/ cron, он мог читать этот каталог только после того, как пользователь действительно вошел в систему. Чтобы убедиться, что каталог зашифрован, проверьте, существует ли этот каталог:
/home/.ecryptfs/<yourusername>
если так, то у вас есть зашифрованный домашний каталог.
Решением для меня было переместить скрипт в незашифрованный каталог, и все работало нормально.
Пытаться
или
systemctl start cron
В моем случае я пытался запустить cron локально. Я проверил статус:
service cron status
Он показал мне:
* cron is not running
Затем я просто запустил службу:
service cron start
если вы используете экземпляр ec2(amazon linux), попробуйте проверить журналы в файле /var/spool/mail/[ec2-user]:
nano /var/spool/mail/[ec2-пользователь]
Я столкнулся с той же проблемой, когда crons не работает. Мы исправили, изменив разрешения и владельца Crons сделал root-владельцем, как мы упоминали в crontab AND Cronjobs 644, данное разрешение
Хотя ответ на этот вопрос был принят, я хотел бы добавить, что сработало для меня. рекомендуется указать URL-адрес в кавычках, если он содержит запрос, он может не работать без кавычек.
НЕ ЗАБУДЬТЕ УКАЗАТЬ ВАШ URL, КОТОРЫЙ СОДЕРЖИТ "?, =, #, %" В ЦИТАТУ.
Пример. https://paystack.com/indexphp?docs/api/#transaction-charge-authorization&amp;date=today должен быть в цитате типа "https://paystack.com/indexphp?docs/api/#transaction-charge-authorization&date". =сегодня"
Иногда команда, которую должен выполнить cron, находится в каталоге, к которому у cron нет доступа, как правило, в системах, где разрешения для домашних каталогов пользователей равны 700, а команда находится в этом каталоге.