Описание тега cron
Название "cron" происходит от слова "chronos", что по-гречески означает "время". Cron позволяет пользователям планировать задания (cronjobs, команды или сценарии оболочки) для периодического запуска в определенное время или в определенные даты.
Он обычно используется для автоматизации обслуживания или администрирования системы, хотя его универсальный характер означает, что его можно использовать для других целей, таких как подключение к Интернету и загрузка электронной почты.
Формат
+---------------- minute (0 - 59)
| +------------- hour (0 - 23)
| | +---------- day of month (1 - 31)
| | | +------- month (1 - 12)
| | | | +---- day of week (0 - 6) (Sunday=0 or 7)
| | | | |
* * * * * command to be executed
Основные команды
crontab -e
Отредактируйте файл crontab.crontab -l
Показать текущую информацию crontab.
Что умеет cron?
Cron может запускать любую команду, которая обычно может стоять сама за себя в командной строке. Например, вы можете запрограммировать cron для запуска java-программы с определенным интервалом (java main.java && java main
).
Популярные вопросы
- Почему знаки процента (%) не работают в crontab?
- cronjob не выполняет скрипт, который отлично работает автономно
- Вариант для приложений с графическим интерфейсом: Cron job: как запустить скрипт, требующий открытия дисплея?
- Почему мой crontab не работает и как я могу устранить его?(канонические вопросы и ответы на serverfault.com)
Исправление проблем
Есть несколько причин, по которым задание cron не запускается должным образом:
Используя знаки процента, как в
date +%F
Неверное время
Добавление или исключение имени пользователя в зависимости от
Cron не работает
Проблемы с синтаксисом или разрешениями
Делать предположения об окружающей среде
Все это описано ниже.
Знаки процента
В crontab знаки процента заменены переводом строки. Это чрезвычайно распространенная проблема в заданиях резервного копирования, которые пытаются архивировать с отметкой времени, например
14 3 0 0 0 tar cfz /backup/file-$(date +%F).tar.gz /home
В %
может быть экранирован обратной косой чертой, но обратная косая черта не удаляется. Это может вызвать дополнительную путаницу, поскольку экранирование работает дляdate +\%F
, но не для wget "http://host/My\%20File.jpg"
.
Вместо этого поместите команду в файл сценария и запустите сценарий из crontab.
Знаки процента могут быть полезны для передачи постоянных данных вашей команде. Простой пример:
59 23 * * * cat >$HOME/cron.out%foo%bar%baz
создаст ~/cron.out с 3 строками "foo", "bar", "baz".
Неверное время
Люди часто ставят 1 * * * * mycommand
в crontab, подождите несколько минут и задайтесь вопросом, почему их задание не выполняется. В данном случае это потому, что временная спецификация означает одну минуту прошедшего каждый час, а не каждую минуту. Попробуйте такой инструмент, как https://crontab.guru/, чтобы проверить свое время.
Чтобы проверить свою работу cron, используйте * * * * *
если вы хотите запускать его часто (каждую минуту) во время тестирования.
Добавление или исключение имени пользователя
В некоторых системах есть /etc/crontab
. В этом файле ожидается имя пользователя после временного интервала, например
57 1 * * * root rkhunter -c -sk
В обычных crontab, как видно с crontab -l
, как для обычных пользователей, так и для root, имя пользователя не разрешено.
Задание не запустится, если имя пользователя добавлено в crontab -e
или опущено в /etc/crontab
.
Убедитесь, что вы знаете, какой тип crontab вы редактируете.
Cron может не работать
Не во всех системах cron установлен и запущен по умолчанию, и используйте, например, anacron
вместо этого для периодического планирования.
ps aux | grep [c]ron
отобразит демон cron, если он запущен.
Если кажется, что он работает, добавьте запись * * * * * touch /tmp/my_cronjob_ran
и проверьте, создается ли файл через минуту. Вы также можете проверить системный журнал, чтобы увидеть список недавно выполненных заданий cron.
Проблемы с синтаксисом или разрешениями
Часто пытаются избежать проблем с оболочкой и символами, помещая команду в файл, но забывая chmod +x
перед добавлением записи crontab.
Перед добавлением в crontab убедитесь, что команда работает в интерактивной оболочке.
Не сбрасывайте вывод проблемной команды! Если у вас проблемы с* * * * * command >/dev/null 2>&1
затем удалите перенаправления и изучите вывод, прежде чем обращаться к нам за помощью.
(Если ваша команда не записывает вывод в файл, демон cron попытается доставить любой вывод по почте. Конечно, для этого требуется, чтобы у вас была настроена и правильно настроена почта.)
См. Также раздел об именах пользователей выше; синтаксис дляcrontab
принадлежит root
отличается от синтаксиса crontab
постоянных пользователей.
Делать предположения об окружающей среде
Графические программы (приложения X11), Java-программы, ssh
а также sudo
заведомо проблематично запускать как задания cron. Это потому, что они полагаются на вещи из интерактивных сред, которые могут отсутствовать в среде cron.
Чтобы более точно смоделировать среду cron в интерактивном режиме, запустите
env -i sh -c 'yourcommand'
Это очистит все переменные среды и запустит sh
который может быть более скудным по функциям, чем ваша текущая оболочка.
Общие проблемы обнаруживаются таким образом:
foo: Command not found
или простоfoo: not found
.Более вероятный
$PATH
установлен в вашем.bashrc
или аналогичный интерактивный файл инициализации. Попробуйте указать все команды по полному пути (или введитеsource ~/.bashrc
в начале скрипта, который вы пытаетесь запустить).Непонятные синтаксические ошибки оболочки
Если ваша интерактивная оболочка
bash
, легко написать сценарий, использующий функции Bash и работающий из командной строки. Ноcron
не работаетbash
, он работаетsh
, который имеет другой набор функций (даже если/bin/sh
символическая ссылка на/bin/bash
)!Если в вашем файле сценария есть правильная строка shebang
#!/bin/bash
тогда он будет запущен запрошенным интерпретатором вместоsh
.unable to open display
Вы пытаетесь запустить графическую программу, но не указываете где (Unix никогда ничего не показывает на "экране", он показывает только "на экране"). Положить
export DISPLAY=:0
в начале вашего скрипта, если вы хотите попробовать открыть программу на первом экране. Это не сработает, если никто не вошел в систему в то время, и может вызвать странности на дисплее коллеги, если кто-то вошел в систему на первом дисплее, но это не вы.Распространенный архитектурный обходной путь - разделить вашу службу на сервер, работающий как безголовый демон, и компонент пользовательского пространства. Попросите клиента пользовательского пространства прослушивать события сервера через какой-либо механизм IPC (файл журнала, сокет, разделяемая память, общая шина, что у вас есть), а затем любой или каждый пользователь может следить за тем, что делает сервер, с довольно минимальными требованиями времени выполнения для сервер; и если они запускают графический дисплей, клиент будет работать в правильно сконфигурированном сеансе, который тривиально имеет доступ к дисплею пользователя, а также к настройкам оконного менеджера, индивидуальным настройкам конфигурации клиента и т. д. (и, если они хотят, они могут вместо этого запустите более простой клиент командной строки, или также, или ни один из них, когда они не хотят отвлекаться и т. д. и т. д.).
Запрос любого пароля
Если
ssh
илиsudo
запрашивает пароль, он завершится ошибкой в cron, так как задания выполняются в фоновом режиме без взаимодействия пользователя с ними. Убедитесь, что они настроены для автоматических, неинтерактивных операций.За
ssh
, это означает установку пары ключей и выполнение этого без парольной фразы (поскольку ssh-agent не используется для разблокировки ключей). Попытка повторить пароль для ssh не работает.За
sudo
, это означает добавление записей вsudoers
чтобы разрешить выполнение команды без пароля и без использования tty. В Unix & Linux Stack Exchange есть несколько сообщений о том, как.
Это все еще не работает!
Таким образом, вы можете запускать простые команды, например touch /tmp/my_cronjob_ran
просто хорошо?
И ваша желаемая команда не содержит %
s и отлично работает с env -i sh -c 'yourcommand'
?
Все еще нормально работает с env -i sh -c 'nohup yourcommand'
или env -i sh -c 'yourcommand </dev/null'
? Если нет, то проблема возникает, когда у него нет стандартного ввода и / или управляющего терминала.
И все же cron не работает?
Добавьте логирование в свою команду с помощью * * * * * yourcommand >> /tmp/mylog 2>&1
затем изучите /tmp/mylog
который будет записывать вывод и ошибки в /tmp/mylog
. Не забывайте это, потому что вы используете>>
(добавить перенаправление), самые новые записи будут в конце файла. У вас могут быть ошибки вверху, и вы обнаружите, что только на полпути вниз вы устранили проблему. Если вы посмотрите только на верхнюю часть файла, вы пропустите изменения, происходящие внизу.
Если после прочтения /tmp/mylog
Вы все еще не знаете, что случилось, пора задать вопрос. Не забудьте включить в свой пост соответствующий вывод из этого файла.