- Debian. Шпаргалка сисадмина. Планировщик задач
- Настройка планировщика Cron в Linux
- Планировщик для linux debian
- Список задач
- Выполнение задания каждую минуту в Crontab
- Как выполнять задание каждую пятницу в час ночи
- Выполняем задание по будним дням в 8:00 утра
- Выполнение через 10 минут после каждого часа 1 числа каждого месяца
- Запуск задания каждые 10 минут
- Специальные слова
- Сохранение выходных данных Crontab
- Отправка выходных данных на e-mail из Crontab
- Отправка выходных данных Crontab только одного задания cronjob
- Игнорирование выходных данных задания Crontab
- Предупреждение
- Cron в Linux: история, использование и устройство
- Содержание
- Происхождение видов
- POSIX crontab
- Хит продаж — Vixie cron 3.0pl1
- Таблица задач и файлы конфигурации
- Расширенный синтаксис
- Среда выполнения задач
- cron в Debian и Ubuntu
- cronie в RedHat, Fedora и CentOS
- cronie в SLES и openSUSE
- Устройство Vixie cron
- Инициализация
- Сбор и обновление списка задач
- Главный цикл
- Запуск задачи
- Послесловие
Debian. Шпаргалка сисадмина. Планировщик задач
Автоматизация рутинных задач — ключ к спокойствию системного администратора, да и к тому же более эффективное использование рабочего времени. Рассмотрение в этом контексте возможностей и нюансов использования планировщиков задач в Debian является вполне закономерным. В этой статье — следующей из серии «Шпаркалка сисадмина» — будут рассмотрены планировщик cron и асинхронный планировщик anacron.
cron — демон, основная задача которого — выполнение запланированных задач.
crontab — программа, используемая для поддержки (создания, удаления, модификации) файлов crontab (располагаются в /var/spool/cron/crontabs) индивидуально для каждого пользователя системы.
anacron — асинхронный (анахроничный) cron; является аналогом cron, только задания выполняет не по расписанию, а через заданные интервалы времени.
Теперь обо всем подробнее.
Cron 1 запускается процессом init из /etc/init.d во время загрузки системы. Основной конфигурационный файл — /etc/crontab. Каждую минуту сron просматривает содержимое каталога /var/spool/cron/crontabs на предмет файлов crontab и если находит их (или обнаруживает, что изменилось время модификации существующих файлов), то загружает (или обновляет, в случае с изменением существующих файлов) их в оперативную память. Эта особенность работы позволяет обойти необходимость перезапуска демона при изменении запланированных задач. Изменять файлы в каталоге /var/spool/cron/crontabs вручную не рекомендуется, для этого используется команда crontab -e.
Каждую минуту cron проверяет все файлы crontab на предмет команд, которые необходимо выполнить в данный момент. После выполнения команды может быть отправлено уведомление по почте владельцу файла crontab (или пользователю, адрес которого определен в переменной MAILTO в /etc/crontab, если он вообще определен).
Также существует заранее определенное поведение планировщика при изменении времени (например переход на летнее и зимнее время) 2 :
Локальные изменения времени меньше чем на 3 часа (например, переход на летнее или зимнее время) обрабатываются специальным образом. Это относится только к задачам, которые запускаются в определенное время или периодом более одного часа. Задачи, которые выполняются чаще, исполняются как обычно.
Если время было переведено вперед, задачи, которые должны были быть выполнены в течение пропущенного интервала, будут запущены немедленно. И наоборот, если время было переведено назад, принимаются меры для предотвращения запуска задачи дважды.
Изменения времени более чем на 3 часа считается коррекцией времени или временной зоны, и новое время начинает использоваться немедленно.
Применительно к Debian существует ряд различий: файлы crontab предварительно разделены на несколько каталогов в зависимости от необходимой частоты выполнения (/etc/cron.hourly — ежечасно, /etc/cron.daily — ежедневно, /etc/cron.weekly — еженедельно, /etc/cron.monthly — ежемесячно). Выполнение заданий в этих каталогах отключено, если установлен anacron (кроме ежечасного задания), чтобы предотвратить конфликты между демонами. Файлы в этих директориях должны удовлетворять ряду требований 3 . Помимо каталогов упомянутых выше, в Debian можно использовать каталог /etc/cron.d, в который также можно поместить файлы с необходимыми командами и которые имеют какое-либо нестандартное расписание выполнения. Требования для файлов в каталогах идентичны.
Теперь подробнее о формате команд.
Каждая команда cron имеет следующую маску:
Допустимо указание нескольких значений через запятую или диапазон значений через тире. При необходимости можно указать шаг значений через слэш («/») — это можно сделать как с использованием чисел (2/3), так и с использованием звездочки (*/2). Если какое-либо из полей не используется, вместо него должна быть звездочка. Если будут указаны только звездочки и не определен ни один из временных параметров, то задание будет выполняться каждую минуту.
Anacron 4 работает несколько иным образом.
Стоить сразу отметить, что anacron по умолчанию не поставляется с дистрибутивом debian, придется его ставить отдельно.
Принципиальное отличие anacron в том, что он рассчитан на асинхронное выполнение команд. Это значит, что даже если сервер был выключен и в этот период должно было выполниться задание, оно обязательно выполнится сразу как сервер окажется включенным. Cron такой функционал предоставить не может и задания выполнены не будут, если в ожидаемое время их выполнения компьютер был выключен.
Формат команд имеет следующий вид:
Anacron предназначен не для замены, но для дополнения cron. Минимальный период выполнения команд — 1 день. При выполнении задачи создается специальный файл в каталоге /var/spool/anacron/ с отметкой времени и при следующей проверке anacron определяет когда последний раз запускалось задание и если время последнего выполнения отличается от текущего больше чем на количество дней, которое определено в команде anacron, то выполняется принудительный запуск задачи с определенной задержкой. Задержка используется главным образом для исключения ситуации одновременного выполнения ресурсоемких задач.
На этом обзор планировщиков закончен. Примеры 5 6 команд широко доступны на различных ресурсах в сети и их публикация в рамках этой статьи будет излишней.
Источник
Настройка планировщика Cron в Linux
Планировщик заданий является по праву одним из важных компонентов системы. По умолчанию, в дистрибутивах Linux, а также FreeBSD, используется планировщик заданий Cron. Рассмотрим как его настроить.
Настроить cron можно несколькими способами. Самый простой и быстрый — указать задание руками в файл /etc/crontab. Проблема в том, что это может сделать только пользователь root.
Структура файла /etc/crontab представляет собой последовательность установок даты и времени, имени пользователя от которого выполняется задача и явное указание исполняемого файла.
# m h dom mon dow user command
# — строка закомментирована, т.е. не выполняется планировщиком
m — минуты. Диапазон значений 0-59
h — часы. Диапазон значений 0-23.
dom — day of month — день месяца (число). Диапазон значений 1-31
mon — месяц. Диапазон значений 1-12
dow — day of week — день недели. указывается числом, где 0 — воскресенье, 6 — суббота.
user — пользователь от которого выполняется задача.
command — выполняемая задача.
Важно! Значения минут, часов, дней месяца, дней недели, а также месяца могут быть * (звездочкой) принимая все доступные значения. Также можно использовать список параметров разделенных запятой.
Примеры разберем подробнее немного позже.
Простым пользователям доступна системная утилита crontab. Для гибкости использования используются параметры:
Используется для редактирования или создания файла расписания для текущего пользователя
Вывод существующих задач в расписании пользователя
Удаление файла расписания текущего пользователя
crontab -u username
Работа с расписаниями указанных пользователей. Выполняется только от пользователя root
Для этого в консоли пишем команду:
Запустится редактор файла используемый по умолчанию (Ubuntu — nano/vi, FreeBSD — ee), в нашем случае mcedit из пакета Midnight Commander.
Синтаксис команд идентичен как и для файла /etc/crontab, за исключением отсутствия параметра имени пользователя. Это значит, что после сохранения файла, все задачи будут выполняться от текущего пользователя.
Сохраняем файл, выходим из редактора и проверяем список заданий crontab -l.
Проверим как работает удаление файла заданий — crontab -r.
Важно! Программа не спрашивает уверены ли вы в удалении файла заданий. Если нужно удалить конкретное задание, следует использовать crontab -e.
Для администратора важно, чтобы не все пользователи могли пользоваться планировщиком. Для этих целей можно использовать файлы /etc/cron.allow и /etc/cron.deny (в некоторых дистрибутивах эти файлы должны размещаться в /etc/cton.d). По умолчанию, использование cron разрешено всем пользователям.
Примеры использования в файле /etc/crontab.
Выполнение задачи каждые 5 минут от пользователя root:
*/5 * * * * root /root/scripts/script1.sh
В полдень и полночь:
0 */12 * * * root /root/scripts/backup.sh
Перезагрузка сервера в 0:00 в первый день месяца (исключительно как пример):
0 0 1 * * root reboot
Выполнение скрипта с понедельника по пятницу в полночь:
0 0 * * 1-5 root /root/script/backup_db.sh
* 0 * * 1-5 root /root/script/backup_db.sh
Ошибка в том, что скрипт будет запускаться с понедельника по пятницу каждую минуту с 0:00 по 0:59
В заданиях назначаемых через crontab -e (т.е. от текущего пользователя) не указывается параметр имени пользователя, в случае примеров — root.
На что еще следует обратить внимание:
Все пути до исполняемых файлов следует писать абсолютными.
Скрипты исполняются из корневой директории, а следовательно, при написании скрипта следует указывать рабочий каталог, либо абсолютные пути до целевых файлов (если в ходе работы скрипта генерируются файлы-отчета и им подобные)
Источник
Планировщик для linux debian
Если у Вас появилась необходимость запускать на ПК/сервере с Linux определенные команды или скрипты через равный промежуток времени или в назначенное время, то на помощь приходит Crontab! Это планировщик заданий (или менеджер, как больше нравится). Таким образом можно запускать задания резервного копирования, синхронизации, обновления, обслуживания системы и многое другое.
Список задач
Crontab (cron происходит от chronos, c греческого «время»; tab означает таблица) — это служба, которая присутствует в Unix и Unix-подобных операционных системах, используется для планирования периодического выполнения команд. Чтобы посмотреть, какие задачи crontab сейчас активны в Вашей системе, введите в окне терминала следующую команду:
Для редактирования списка заданий можно запустить:
Это откроет редактор по-умолчанию, чтобы изменять задания crontab. После сохранения файла в редакторе, задания обновятся. Формат записей таков:
Как мы видим, в самом начале идет 5 звезд. Звезды представляют собой различные части даты, их последовательность следующая:
- минута (от 0 до 59)
- час (с 0 до 23)
- день месяца (с 1 по 31)
- месяц (от 1 до 12)
- день недели (от 0 до 6) (0=воскресенье)
Выполнение задания каждую минуту в Crontab
Если Вы установите звездочку, это будет означать буквально все. Например, такая запись, как была выше, определяет выполнение задания каждую минуту:
Задание будет выполняться: каждую минуту, каждый час, каждый день месяца, каждый месяц, и так каждый день на неделе.
Как выполнять задание каждую пятницу в час ночи
Если мы хотим запланировать запуск скрипта в час ночи каждую пятницу, нам понадобится следующая запись в cron:
Выполняем задание по будним дням в 8:00 утра
Выполнение через 10 минут после каждого часа 1 числа каждого месяца
Честно говоря, все не так сложно, верно? Просто это требует некоторой практики.
Запуск задания каждые 10 минут
Это можно было бы сделать так:
Но это не будет красивым решением. Правильнее сделать так:
Специальные слова
В самом начале взамен звездочек применяйте специальные слова:
Пример задания, которое будет выполняться каждый день в 00:00:
Сохранение выходных данных Crontab
По-умолчанию cron сохраняет выходные /bin/execute/this/script.sh данные в почтовый ящик пользователя (в данном случае root). Но это красивее, если выход будет сохраняться в отдельном логе. Сделаем это так:
Linux может создавать журналы на разных уровнях. Стандартный выход (STDOUT) и стандартные ошибки (STDERR). STDOUT помечается как 1, STDERR-как 2. Так что… следующая инструкция говорит Linux хранить STDERR в STDOUT, а также, создать один поток данных для сообщений и ошибок:
Теперь, когда у нас есть 1 выходной поток, мы можем вылить его в файл. Если знак больше один (>) файл будет перезаписываться, два знака больше (>>) данные всегда будут добавляться к файлу в конец. В нашем случае мы хотели бы добавлять данные:
Отправка выходных данных на e-mail из Crontab
По умолчанию cron шлет выходные данные на почтовый ящик локального пользователя. Но мы можем настроить Crontab для перенаправления всех выходных данных на реальный адрес электронной почты, добавив следующую переменную в crontab:
Отправка выходных данных Crontab только одного задания cronjob
Если Вы хотите получать по почте выходные данные задания, установите этот пакет:
И добавить в задание вот что:
Игнорирование выходных данных задания Crontab
Делается это очень просто:
Мы передаем вывод в /dev/null это специальный файл, который отбрасывает все данные (нулевое устройство, «черная дыра»).
Предупреждение
Многие скрипты исполняются в среде Bash с переменной PATH. И поэтому может случиться так, что Ваши скрипты работают в Вашей оболочке, но когда запустите в Cron (где PATH переменная отличается), скрипту не удается найти указанные исполняемые файлы и задание завершается ошибкой. Поэтому используйте в файле заданий Crontab специальную переменную PATH:
Источник
Cron в Linux: история, использование и устройство
Классик писал, что счастливые часов не наблюдают. В те дикие времена ещё не было ни программистов, ни Unix, но в наши дни программисты знают твёрдо: вместо них за временем проследит cron.
Утилиты командной строки для меня одновременно слабость и рутина. sed, awk, wc, cut и другие старые программы запускаются скриптами на наших серверах ежедневно. Многие из них оформлены в виде задач для cron, планировщика родом из 70-х.
Я долго пользовался cron поверхностно, не вникая в детали, но однажды, столкнувшись с ошибкой при запуске скрипта, решил разобраться основательно. Так появилась эта статья, при написании которой я ознакомился с POSIX crontab, основными вариантами cron в популярных дистрибутивах Linux и устройством некоторых из них.
Используете Linux и запускаете задачи в cron? Вам интересна архитектура системных приложений в Unix? Тогда нам по пути!
Содержание
Происхождение видов
Периодическое выполнение пользовательских или системных программ — очевидная необходимость во всех операционных системах. Поэтому потребность в сервисах, позволяющих централизованно планировать и выполнять задачи, программисты осознали очень давно.
Unix-подобные операционные системы ведут свою родословную от Version 7 Unix, разработанной в 70-х годах прошлого века в Bell Labs в том числе и знаменитым Кеном Томпсоном (англ. Ken Thompson). Вместе c Version 7 Unix поставлялся и cron, сервис для регулярного выполнения задач суперпользователя.
Типичный современный cron — несложная программа, но алгоритм работы оригинального варианта был ещё проще: сервис просыпался раз в минуту, читал табличку с задачами из единственного файл (/etc/lib/crontab) и выполнял для суперпользователя те задачи, которые следовало выполнить в текущую минуту.
Впоследствии усовершенствованные варианты простого и полезного сервиса поставлялись со всеми Unix-подобными операционными системами.
Обобщённые описания формата crontab и базовых принципов работы утилиты в 1992 году были включены в главный стандарт Unix-подобных операционных систем — POSIX — и таким образом cron из стандарта де-факто стал стандартом де-юре.
В 1987 году Пол Викси (англ. Paul Vixie), опросив пользователей Unix на предмет пожеланий к cron, выпустил ещё одну версию демона, исправляющую некоторые проблемы традиционных cron и расширяющую синтаксис файлов-таблиц.
К третьей версии Vixie cron стал отвечать требованиям POSIX, к тому же у программы была либеральная лицензия, вернее не было вообще никакой лицензии, если не считать пожеланий в README: гарантий автор не даёт, имя автора удалять нельзя, а продавать программу можно только вместе с исходным кодом. Эти требования оказались совместимы с принципами набиравшего в те годы популярность свободного ПО, поэтому некоторые ключевые из появившихся в начале 90-х дистрибутивов Linux взяли Vixie cron в качестве системного и развивают его до сих пор.
В частности, Red Hat и SUSE развивают форк Vixie cron — cronie, а Debian и Ubuntu используют оригинальное издание Vixie cron со множеством патчей.
Давайте для начала познакомимся с описанной в POSIX пользовательской утилитой crontab, после чего разберём расширения синтаксиса, представленные в Vixie cron, и использование вариаций Vixie cron в популярных дистрибутивах Linux. И, наконец, вишенка на торте — разбор устройства демона cron.
POSIX crontab
Если оригинальный cron всегда работал для суперпользователя, то современные планировщики чаще имеют дело с задачами обычных пользователей, что более безопасно и удобно.
Сron-ы поставляются комплектом из двух программ: постоянно работающего демона cron и доступной пользователям утилиты crontab. Последняя позволяет редактировать таблицы задач, специфичные для каждого пользователя в системе, демон же запускает задачи из пользовательских и системной таблиц.
В стандарте POSIX никак не описывается поведение демона и формализована только пользовательская программа crontab. Существование механизмов запуска пользовательских задач, конечно, подразумевается, но не описано подробно.
Вызовом утилиты crontab можно сделать четыре вещи: отредактировать пользовательскую таблицу задач в редакторе, загрузить таблицу из файла, показать текущую таблицу задач и очистить таблицу задач. Примеры работы утилиты crontab:
При вызове crontab -e будет использоваться редактор, указанный в стандартной переменной окружения EDITOR .
Сами задачи описаны в следующем формате:
Первые пять полей записей: минуты [1..60], часы [0..23], дни месяца [1..31], месяцы [1..12], дни недели [0..6], где 0 — воскресенье. Последнее, шестое, поле — строка, которая будет выполнена стандартным интерпретатором команд.
В первых пяти полях значения можно перечислять через запятую:
Или через дефис:
Доступ пользователей к планированию задач регулируется в POSIX файлам cron.allow и cron.deny в которых перечисляются, соответственно, пользователи с доступом к crontab и пользователи без доступа к программе. Расположение этих файлов стандарт никак не регламентирует.
Запускаемым программам, согласно стандарту, должны передаваться по меньшей мере четыре переменные окружения:
- HOME — домашняя директория пользователя.
- LOGNAME — логин пользователя.
- PATH — путь, по которому можно найти стандартные утилиты системы.
- SHELL — путь к использованному командному интерпретатору.
Примечательно, что POSIX ничего не говорит о том, откуда берутся значения для этих переменных.
Хит продаж — Vixie cron 3.0pl1
Общий предок популярных вариантов cron — Vixie cron 3.0pl1, представленный в рассылке comp.sources.unix в 1992 году. Основные возможности этой версии мы и рассмотрим подробнее.
Vixie cron поставляется в двух программах (cron и crontab). Как обычно, демон отвечает за чтение и запуск задач из системной таблицы задач и таблиц задач отдельных пользователей, а утилита crontab — за редактирование пользовательских таблиц.
Таблица задач и файлы конфигурации
Таблица задач суперпользователя расположена в /etc/crontab. Синтаксис системной таблицы соответствует синтаксису Vixie cron с поправкой на то, что в ней шестой колонкой указывается имя пользователя, от лица которого запускается задача:
Таблицы задач обычных пользователей располагаются в /var/cron/tabs/username и используют общий синтаксис. При запуске утилиты crontab от имени пользователя редактируются именно эти файлы.
Управление списками пользователей, имеющих доступ к crontab, происходит в файлах /var/cron/allow и /var/cron/deny, куда достаточно внести имя пользователя отдельной строкой.
Расширенный синтаксис
По сравнению с POSIX crontab решение Пола Викси содержит несколько очень полезных модификаций в синтаксисе таблиц задач утилиты.
Стал доступен новый синтаксис таблиц: например, можно указывать дни недели или месяцы поимённо (Mon, Tue и так далее):
Можно указывать шаг, через который запускаются задачи:
Шаги и интервалы можно смешивать:
Поддерживаются интуитивные альтернативы обычному синтаксису (reboot, yearly, annually, monthly, weekly, daily, midnight, hourly):
Среда выполнения задач
Vixie cron позволяет менять окружение запускаемых приложений.
Переменные окружения USER, LOGNAME и HOME не просто предоставляются демоном, а берутся из файла passwd. Переменная PATH получает значение «/usr/bin:/bin», а SHELL — «/bin/sh». Значения всех переменных, кроме LOGNAME, можно изменить в таблицах пользователей.
Некоторые переменные окружения (прежде всего SHELL и HOME) используются самим cron для запуска задачи. Вот как может выглядеть использование bash вместо стандартного sh для запуска пользовательских задач:
В конечном итоге все определённые в таблице переменные окружения (используемые cron или необходимые процессу) будут переданы запущенной задаче.
Для редактирования файлов утилитой crontab используется редактор, указанный в переменной окружения VISUAL или EDITOR. Если в среде, где был запущен crontab, эти переменные не определены, то используется «/usr/ucb/vi» (ucb — это, вероятно, University of California, Berkeley).
cron в Debian и Ubuntu
Разработчики Debian и производных дистрибутивов выпустили сильно модифицированную версию версию Vixie cron 3.0pl1. Отличий в синтаксисе файлов-таблиц нет, для пользователей это тот же самый Vixie cron. Крупнейшие новые возможности: поддержка syslog, SELinux и PAM.
Из менее заметных, но осязаемых изменений — расположение конфигурационных файлов и таблиц задач.
Пользовательские таблицы в Debian располагаются в директории /var/spool/cron/crontabs, системная таблица всё там же — в /etc/crontab. Специфичные для пакетов Debian таблицы задач помещаются в /etc/cron.d, откуда демон cron их автоматически считывает. Управление доступом пользователей регулируется файлами /etc/cron.allow и /etc/cron.deny.
В качестве командной оболочки по умолчанию по-прежнему используется /bin/sh, в роли которого в Debian выступает небольшой POSIX-совместимый шелл dash, запущенный без чтения какой-либо конфигурации (в неинтерактивном режиме).
Сам cron в последних версиях Debian запускается через systemd, а конфигурацию запуска можно посмотреть в /lib/systemd/system/cron.service. Ничего особенного в конфигурации сервиса нет, любое более тонкое управление задачами возможно осуществить через переменные окружения, объявленные прямо в crontab каждого из пользователей.
cronie в RedHat, Fedora и CentOS
cronie — форк Vixie cron версии 4.1. Как и в Debian, синтаксис не менялся, но добавлена поддержка PAM и SELinux, работы в кластере, слежения за файлами при помощи inotify и других возможностей.
Конфигурация по умолчанию находится в обычных местах: системная таблица — в /etc/crontab, пакеты помещают свои таблицы в /etc/cron.d, пользовательские таблицы попадают в /var/spool/cron/crontabs.
Демон запускается под управлением systemd, конфигурация сервиса — /lib/systemd/system/crond.service.
В Red Hat-подобных дистрибутивах при запуске по умолчанию используется /bin/sh, в роли которого выступает стандартный bash. Надо заметить, что при запуске задач cron через /bin/sh командная оболочка bash запускается в POSIX-совместимом режиме и не читает никакой дополнительной конфигурации, работая в неинтерактивном режиме.
cronie в SLES и openSUSE
Немецкий дистрибутив SLES и его дериватив openSUSE используют всё тот же cronie. Демон здесь тоже запускается под systemd, конфигурация сервиса лежит в /usr/lib/systemd/system/cron.service. Конфигурация: /etc/crontab, /etc/cron.d, /var/spool/cron/tabs. В качестве /bin/sh выступает тот же самый bash, запущенный в POSIX-совместимом неинтерактивном режиме.
Устройство Vixie cron
Современные потомки cron по сравнению с Vixie cron не изменились радикально, но всё же обзавелись новыми возможностями, не требующимися для понимания принципов работы программы. Многие из этих расширений оформлены неаккуратно и путают код. Оригинальный же исходный код cron в исполнении Пола Викси читать одно удовольствие.
Поэтому разбор устройства cron я решил провести на примере общей для обеих ветвей развития cron программы — Vixie cron 3.0pl1. Примеры я упрощу, убрав усложняющие чтение ifdef-ы и опустив второстепенные детали.
Работу демона можно разделить на несколько этапов:
- Инициализация программы.
- Сбор и обновление списка задач для запуска.
- Работа главного цикла cron.
- Запуск задачи.
Разберём их по порядку.
Инициализация
При запуске после проверки аргументов процесса cron устанавливает обработчики сигналов SIGCHLD и SIGHUP. Первый вносит в лог запись о завершении работы дочернего процесса, второй — закрывает файловый дескриптор файла-лога:
Демон cron в системе всегда работает один, только в роли суперпользователя и из главной директории cron. Следующие вызовы создают файл-лок с PID-ом процесса-демона, убеждаются, что пользователь правильный и меняют текущую директорию на главную:
Выставляется путь по умолчанию, который будет использоваться при запуске процессов:
Дальше процесс «демонизируется»: создаёт дочернюю копию процесса вызовом fork и новую сессию в дочернем процессе (вызов setsid). В родительском процессе больше надобности нет — и он завершает работу:
Завершение родительского процесса высвобождает лок на файле-локе. Кроме того, требуется обновить PID в файле на дочерний. После этого заполняется база задач:
Дальше cron переходит к главному циклу работы. Но перед этим стоит взглянуть на загрузку списка задач.
Сбор и обновление списка задач
За загрузку списка задач отвечает функция load_database. Она проверяет главный системный crontab и директорию с пользовательскими файлами. Если файлы и директория не менялись, то список задач не перечитывается. В противном случае начинает формироваться новый список задач.
Загрузка системного файла со специальными именами файла и таблицы:
Загрузка пользовательских таблиц в цикле:
После чего старая база данных подменяется новой.
В примерах выше вызов функции process_crontab убеждается в существовании пользователя, соответствующего имени файла таблицы (если только это не суперпользователь), после чего вызывает load_user. Последняя уже читает сам файл построчно:
Здесь либо выставляется переменная окружения (строки вида VAR=value) функциями load_env / env_set, либо читается описание задачи (* * * * * /path/to/exec) функцией load_entry.
Сущность entry, которую возвращает load_entry, — это и есть наша задача, помещаемая в общий список задач. В самой функции проводится многословный разбор формата времени, нас же больше интересует формирование переменных окружения и параметров запуска задачи:
С актуальным списком задач и работает главный цикл.
Главный цикл
Оригинальный cron из Version 7 Unix работал совсем просто: в цикле перечитывал конфигурацию, запускал суперпользователем задачи текущей минуты и спал до начала следующей минуты. Этот простой подход на старых машинах требовал слишком много ресурсов.
В SysV была предложена альтернативная версия, в которой демон засыпал либо до ближайшей минуты, для которой определена задача, либо на 30 минут. Ресурсов на перечитывание конфигурации и проверку задач в таком режиме потреблялось меньше, но быстро обновлять список задач стало неудобно.
Vixie cron вернулся к проверке списков задач раз в минуту, благо к концу 80-х ресурсов на стандартных Unix-машинах стало значительно больше:
Непосредственно выполнением задач занимается функция cron_sleep, вызывающая функции job_runqueue (перебор и запуск задач) и do_command (запуск каждой отдельной задачи). Последнюю функцию стоит разобрать подробнее.
Запуск задачи
Функция do_command исполнена в хорошем Unix-стиле, то есть для асинхронного выполнения задачи она делает fork. Родительский процесс продолжает запуск задач, дочерний — занимается подготовкой процесса задачи:
В child_process довольно много логики: она принимает стандартные потоки вывода и ошибок на себя, чтобы потом переслать на почту (если в таблице задач указана переменная окружения MAILTO), и, наконец, ждёт завершения работы основного процесса задачи.
Процесс задачи формируется еще одним fork:
Вот, в общем-то, и весь cron. Какие-то интересные детали, например учёт удалённых пользователей, я опустил, но главное изложил.
Послесловие
Сron — на удивление простая и полезная программа, выполненная в лучших традициях мира Unix. Она не делает ничего лишнего, но свою работу выполняет замечательно на протяжении уже нескольких десятилетий. Ознакомление с кодом той версии, что поставляется с Ubuntu, заняло не больше часа, а удовольствия я получил массу! Надеюсь, я смог поделиться им с вами.
Не знаю, как вам, но мне немного грустно осознавать, что современное программирование с его склонностью к переусложнению и переабстрагированию уже давно не располагает к подобной простоте.
Существует множество современных альтернатив cron: systemd-timers позволяют организовать сложные системы с зависимостями, в fcron можно гибче регулировать потребление ресурсов задачами. Но лично мне всегда хватало простейших crontab.
Словом, любите Unix, используйте простые программы и не забывайте читать маны для вашей платформы!
Источник