Коротко: CRON запускает скрипты по расписанию, incron — по изменению файлов; вместе они закрывают фоновую автоматизацию на Linux.
CRON — системный планировщик задач в Linux: фоновый сервис, который запускает нужные скрипты по расписанию — раз в минуту, час, день, неделю, месяц или по заданному интервалу. А incron — его «событийный» родственник: запускает команды не по времени, а по изменению файлов. Разберём синтаксис обоих и типовые примеры из практики разработки.
CRON стартует вместе с системой и работает в фоне; его единственная задача — выполнять заданные скрипты в нужное время.
Как настроить CRON?
Чтобы открыть настройки cron, выполните:
crontab -e
Флаг -e открывает временный файл в вашем редакторе по умолчанию — там уже перечислены текущие правила, туда же добавляются новые. После сохранения файл обрабатывается, а правила попадают в /var/spool/cron/crontabs/<имя_пользователя>. Важный нюанс: задачи выполняются от имени того пользователя, который их добавил. Поэтому, если скрипт должен работать от конкретного пользователя, — запускайте команду из-под него.
Синтаксис строки crontab такой:
minute hour day month day_of_week /path/to/executable/file
Примеры расписаний crontab
Допустим, есть скрипт /home/www/bin/console app:cache:clear, и его нужно как-то запускать. Какие есть варианты?
Каждую минуту:
* * * * * /home/www/bin/console app:cache:clear
Каждый час в нулевую минуту:
0 * * * * /home/www/bin/console app:cache:clear
Каждый день в полночь (нулевая минута нулевого часа):
0 0 * * * /home/www/bin/console app:cache:clear
В конкретный день месяца, например 15-го:
0 0 15 * * /home/www/bin/console app:cache:clear
В первый день недели первого месяца года, в 00:00:
0 0 * 1 0 /home/www/bin/console app:cache:clear
В нулевой день недели каждого месяца:
0 0 * * 0 /home/www/bin/console app:cache:clear
В произвольное время — например, во вторник в 15:30:
30 15 * * 2 /home/www/bin/console app:cache:clear
День недели можно писать сокращённо, например sun — воскресенье:
30 15 * * sun /home/www/bin/console app:cache:clear
Интервал задаётся через - — например, каждый час с 7 утра до 7 вечера:
0 7-19 * * * /home/www/bin/console app:cache:clear
Несколько запусков перечисляются через , — например, в 16:05 и 16:35 каждый день:
5,35 16 * * * /home/www/bin/console app:cache:clear
Можно не указывать конкретное время, а задать шаг — например, раз в 10 минут:
*/10 * * * * /home/www/bin/console app:cache:clear
Готовые сокращения расписаний
Помимо явного синтаксиса есть набор удобных псевдонимов:
- @reboot — один раз при загрузке системы;
- @yearly, @annually — раз в год;
- @monthly — раз в месяц;
- @weekly — раз в неделю;
- @daily, @midnight — каждый день;
- @hourly — каждый час.
Например, запуск раз в час:
@hourly /home/www/bin/console app:cache:clear
Как не плодить дубликаты процессов?
Иногда нужно, чтобы скрипт всегда работал в одном экземпляре. Например, задача запускается раз в минуту, но порой выполняется дольше минуты — без защиты в следующую минуту стартует второй экземпляр. Решает это утилита setlock:
* * * * * /usr/local/bin/setlock -nx /tmp/cache_clear /usr/bin/php /home/www/bin/console app:cache:clear
Здесь setlock создаёт файл-блокировку /tmp/cache_clear и не запускает дубликаты, пока предыдущий процесс не завершится. Часто очень выручает.
incron: запуск по событиям файловой системы
incron отслеживает состояние файлов и по событию выполняет заданное действие. Пример пользы: перезагрузить nginx при изменении его конфига. Скажем, в приложении есть блокировка пользователей по IP — вы дописываете IP в конфиг, а incron ловит изменение файла и перезапускает nginx, применяя настройки.
Если incron не установлен:
sudo apt install incron
Редактирование правил — по аналогии с cron:
incrontab -e
Формат записи простой:
<path> <mask> <command>
<path> — путь до файла или директории, за которой следим. <mask> — одно из событий:
- IN_ACCESS — к файлу был получен доступ (файл прочитан);
- IN_ATTRIB — изменены метаданные файла (permissions, timestamps, extended attributes и т.д.);
- IN_CLOSE_WRITE — закрыт файл, открытый на запись;
- IN_CLOSE_NOWRITE — закрыт файл, открытый не на запись;
- IN_CREATE — в отслеживаемой директории создан файл или каталог;
- IN_DELETE — в отслеживаемой директории удалён файл или каталог;
- IN_DELETE_SELF — удалён сам отслеживаемый файл или каталог;
- IN_MODIFY — отслеживаемый файл изменён;
- IN_MOVE_SELF — отслеживаемый файл или каталог перемещён;
- IN_MOVED_FROM — файл перемещён из отслеживаемой директории;
- IN_MOVED_TO — файл перемещён в отслеживаемую директорию;
- IN_OPEN — файл был открыт.
<command> — команда, выполняемая по триггеру. В ней можно использовать подстановки:
- $$ — знак доллара;
- $@ — путь к отслеживаемой файловой системе;
- $# — имя файла, вызвавшего событие;
- $% — флаг события в текстовом виде;
- $& — флаг события в числовом виде.
После настройки incron нужно запустить:
/etc/init.d/incrond start
OR
systemctl start incron.service
Проверить статус сервиса:
systemctl status incron.service
Возможно, также придётся добавить пользователя в /etc/incron.allow — это нужно, если у него ещё нет доступа к сервису incron.
Несколько примеров правил:
/etc/apache2/apache2.conf IN_MODIFY /usr/sbin/service apache2 stop
/tmp/gfg/myfile.txt IN_ACCESS echo "$$ $@ $# $% $&" # вывод увидим в /var/log/syslog
cron закрывает запуск по расписанию, incron — реакцию на изменения файлов. Вместе они покрывают большинство задач фоновой автоматизации на Linux-сервере. Если нужно выстроить надёжную фоновую обработку на проде — помогу на консультации.
Незаметно отвалившийся крон — классическая боль. Cron-мониторинг (heartbeat) в Gotcha присылает уведомление, если задача не отметилась в срок.
Stas
3 ноября 2023, 05:52Ох, был бы ты на неделю раньше и это сэкономило бы мне два вечера сражений с кроном)