Настройка cron astra linux

Обновлено: 02.07.2024

В данном посте обсуждаются базовые принципы написания скриптов и работа планировщика заданий в Oracle Linux. Рассматриваются следующие вопросы:

1. Скрипты в ОС Linux

Скрипты в ОС на базе Linux – это набор команд, записанных в файл. Это делается с целью быстрого и удобного вызова последовательности этих команд. Скрипты могут выполнять самые разные задачи – от автоматизации рутинных действий системного администратора до реализации сложных алгоритмов для ИТ инфраструктуры. При этом результаты работы команд могут служить входными данными для других задач (команд).

Пример ошибки, когда запускается неисполняемый файл:

Права на исполнение даются командой chmod. Например,

chmod +x filename.sh

Данная команда дает всем пользователям операционной системы право на запуск файла с именем filename.sh

Право на запуск того же файла только владельцу можно дать следующей командой: chmod u+x filename.sh.

Расширение .sh не обязательно, но таким образом легче определять, какой файл является скриптом.

Ниже рассматривается пример написания простейшего скрипта, копирующего все файлы из папки /home/rustam/Documents в папку /tmp/backup.

При работе со скриптами могут использоваться переменные. Они позволяют хранить в файле сценария различную информацию, например, результаты работы одних команд для дальнейшего их использования для других команд.

Исполнение отдельных команд без хранения результатов работы ограничивают их возможности.

Существуют два типа переменных, которые используются в bash-скриптах:

Используются при необходимости работы с системными данными в командах оболочки. Например, требуется вывести домашнюю директорию текущего пользователя. Список переменных для среды конкретного пользователя выдается командой env.

Можно использовать системную переменную $HOME в двойных кавычках, что не помешает ее распознаванию системой.

В дополнение к переменным среды, bash-скрипты позволяют задавать и использовать в скрипте свои собственные переменные. Подобные переменные хранят значение до тех пор, пока не завершится выполнение сценария. Как и в случае с системными переменными, к пользовательским переменным обращаются используя знак доллара:

Дополним соответствующим образом скрипт, написанный ранее – добавляется переменная для хранения пути к папке, в которую осуществляется копирование.

2. Что такое планировщик заданий. Работа сервиса cron.

Часто возникают ситуации, в которых приходится автоматизировать различные задачи по обслуживанию и работе с Linux с помощью скриптов. В этом случае удобно, если скрипт выполняет необходимые команды без участия пользователя. Для этого настраивается автоматический запуск требуемого скрипта в заданное время.

Для указанной настройки в Linux используется системный сервис cron. Это планировщик, который позволяет выполнять необходимые скрипты раз в час, раз в день, неделю или месяц, а также в любое заданное время или через любой интервал времени. Сервис cron также часто используется другими службами операционной системы.

Для настройки времени, даты и интервала выполнения задания, используется специальный синтаксис файла cron и специальная команда. Не рекомендуется непосредственно редактировать файл /etc/crontab. Вместо этого используется команда crontab. Ниже запускается команда crontab с ключом –e для редактирования файла

Рекомендуется ее выполнять с опцией -e, тогда для редактирования правил используется текстовый редактор по умолчанию. После выполнения команды открывается временный файл, в котором записаны текущие правила cron и есть возможность добавлять новые. Добавленные правила запускаются именно от того пользователя, от имени которого они были добавлены.

Файлы crontab, используемые для управления работой планировщика, располагаются в каталоге /etc/cron.d/. Кроме того, в каталогах /etc/cron.daily/, /etc/cron.weekly/ и /etc/cron.monthly/ размещаются автоматически запускаемые программы (ежедневно, еженедельно или ежемесячно).

Вывод содержимого текущего файла позволяет команда:

Таблица crontab состоит из 6 колонок, которые разделяются пробелами или табуляторами. Первые пять колонок отвечают за время выполнения, соответственно, минута, час, день месяца, месяц, день недели. В них может находиться: число, список чисел (1,2,3), диапазон чисел (1-3), символы * или /. Все остальные символы в строке интерпретируются как выполняемая команда с ее параметрами – можно указать как саму команду (например, echo “Доброе утро”), так и путь к исполняемому скрипту.


Как запускать скрипты через cron

Скрипты запускаются через cron, указанием команды либо пути к скрипту в последней колонке.

Обязательно требуется прописывать полный путь к команде, так как для команд, запускаемых от имени сервиса cron, переменная пользовательской среды PATH будет отличаться, и сервис не сможет найти команду.

Пример запуска ранее созданного скрипта filename.sh, который копирует файлы каждый день в 23:00:

или копирует файлы каждые 5 минут:

3. Примеры

Ниже приведены примеры настройки и работы cron:

Главное окно программы, выполняемой от имени администратора (рис. 1), содержит меню (Меню), кнопки-переключатели режима отображения расписания задач и переменных окружения (Кнопки-переключатели режима отображения), панели «Запланированные задачи» (Панель «Запланированные задачи») и «Переменные окружения» (Панель «Переменные окружения») с кнопками сопровождения.


    Меню программы содержит следующие пункты:
  • «Файл»:
    • «Загрузить» - в соответствии с установленным режимом отображения загружается файл настроек программы с расписанием задач и переменными окружения;
    • «Сохранить» - расписание задач и переменные окружения сохраняются в файле настроек программы;
    • «Выход» - если настройки не изменялись, то работа программы завершается. В противном случае открывается окно с запросом на подтверждение сохранения конфигурации:
      • [Да] - новые значения сохраняются в файле настроек программы, окно закрывается, и работа программы завершается;
      • [Нет] - окно закрывается, и работа программы завершается;
      • [Отмена] - окно закрывается;
      • «Содержание» - вызов окна справки;
      • «О программе. » - вызов окна с краткой информацией о программе.

      Кнопки-переключатели режима отображения

      Кнопками-переключателями устанавливается режим отображения данных на панелях «Запланированные задачи» (Панель «Запланированные задачи») и «Переменные окружения» (Панель «Переменные окружения»).

        В режиме администратора все данные, из числа сохраняемых в файле настроек программы, доступны для редактирования, и существуют следующие режимы отображения (см. рис. 1):
      • «Показать для системы» - отображаются системные данные;
      • «Показать для пользователя» - отображаются данные, установленные для пользователя, указанного в строке справа от кнопки (устанавливается из выпадающего списка).

      Панель «Запланированные задачи»

        На панели «Запланированные задачи» (см. рис. 1) в табличном виде отображается расписание задач:
      • «Пользователь» (только в режиме отображения «Показать для системы») - пользователь, от имени которого выполняется задача;
      • «Расписание» (только в режиме отображения «Показать для системы») - краткое описание начала выполнения задачи: перечисляются минуты, часы, дни месяца, месяцы и дни недели (символ * в соответствующей позиции обозначает: ежеминутно, ежечасно, каждый день, каждый месяц, каждый день недели);
      • «Команда» - имя программы, назначенной к выполнению, в рамках данной задачи;
      • «Состояние» - разрешение или запрет задачи к выполнению;
      • «Описание» - сопроводительный текст;
      • «Подробнее» - подробное описание установленного времени начала выполнения задачи (расшифровывается символ * из столбца «Расписание»).

      Щелчок левой кнопкой мыши на строке таблицы выделяет ее. Несколько строк (задач) выделяются щелчком левой кнопки мыши на каждой строке при удержании клавиши <Ctrl>.

      Время запуска установленных задач определяется по системным дате и времени.

      Контекстное меню


        Щелчком правой кнопки мыши на панели «Запланированные задачи» открывается контекстное меню:
      • «Новая задача. » - открывается окно «Новая задача» (рис. 2):
      • «Команда» - в стоке или из диалогового окна устанавливается полное или относительное (если имя каталога с программой находится среди значений переменной окружения PATH) имя программы, назначенной к выполнению в рамках данной задачи, вместе, если это необходимо, со значениями аргументов и параметров ввода командной строки. Кнопками справа от строки ввода открывается диалоговое окно для выбора и установки (слева направо) имени файла или пункта главного меню (подменю) рабочего стола. После подтверждения или отмены установки имени файла или пункта меню (подменю) окно закрывается, и установленное имя файла или приложения, запускаемого из установленного пункта меню, соответственно, отображается или не отображается в строке ввода команды;
      • «Запустить как» (только при установленном режиме отображения «Показать для системы» в главном окне) - из выпадающего списка устанавливается имя пользователя от имени которого программа, назначенная в строке «Команда», запускается;
      • флаг «Графическое приложение» - при включении добавляет, а при выключении убирает выставление переменной окружения DISPLAY в строке «Команда»;
      • «Запустить как» (только в режиме отображения «Показать для системы») - из списка устанавливается пользователь, от имени которого выполняется команда;
      • «Комментарий» - устанавливается сопроводительный текст;
      • флаг «Разрешить задачу» - устанавливает разрешение или запрет команды к выполнению;
      • флаг«Запускать при загрузке системы» - устанавливает запуск команды при загрузке системы;
      • флаг «Запускать каждый день» - устанавливает ежедневный запуск команды;
      • «Месяцы» - устанавливаются месяцы запуска команды;
      • «Дни месяца» - устанавливаются дни запуска команды;
      • «Часы» - устанавливаются часы запуска команды;
      • «Дни недели» - устанавливаются дни недели запуска команды;
      • «Минуты» - устанавливаются непосредственно минуты, или из выпадающего списка «Шаблон» устанавливается минутный режим запуска команды;
      • [Да] - устанавливается новая задача в расписании, в таблице появляется соответствующая запись, и окно закрывается;
      • [Отмена] - новая задача не устанавливается, окно закрывается;
      • [Да] - выделенные задачи удаляются из расписания, и окно закрывается;
      • [Нет] - окно закрывается;
      • [Да] - окно закрывается, и команда начинает выполняться;
      • [Нет] - окно закрывается.

      Кнопки сопровождения

      Кнопки сопровождения располагаются справа от панели «Запланированные задачи» (см. рис. 1) и повторяют аналогичные пункты контекстного меню (см. Контекстное меню): [Новая задача. ], [Правка. ], [Удалить], [Запустить сейчас]; [Печать. ] - открывает диалоговое окно «Печать» (Окно «Печать»).

      Окно «Печать»

      В окне «Печать» (рис. 3) устанавливаются параметры и выполняется печать на устройстве или запись в файл (в формате PDF) расписания задач и переменных окружения, отображаемых на панелях «Запланированные задачи» и «Переменные окружения».


        Окно содержит следующие управляющие элементы:
      • поле «Принтер»:
        • «Название» - в строке из выпадающего списка доступных принтеров устанавливается имя принтера или печать в файл. Ниже, в соответствии с установками описания принтера отображаются его свойства: «Расположение» и «Тип»;
        • «Вывод в файл» - в строке ввода или с помощью кнопки вызова диалогового окна [. ] (справа от строки) устанавливается имя файла для записи. Диалоговое окно после подтверждения или отмены установки закрывается, и новое имя файла, соответственно, устанавливается или не устанавливается;
        • поле «Двусторонняя печать» - кнопками-переключателями «Нет», «По длинной стороне», «По короткой стороне» устанавливается, соответственно, односторонняя печать, оборотная печать c книжной ориентацией страницы и оборотная печать с альбомной ориентацией страницы;
        • поле «Режим цвета» - кнопками-переключателями «Цвет», «Оттенки серого» устанавливается, соответственно, цветная и полутоновая (оттенки серого) печать;

        Панель «Переменные окружения»

          На панели «Переменные окружения» (см. рис. 1) в табличном виде отображается перечень переменных окружения, установленных для всех задач расписания:
        • «Переменная» - имя переменной;
        • «Значение» - значение переменной;
        • «Состояние» - разрешение или запрет установки переменной;
        • «Комментарий» - сопроводительный текст.

        Щелчком левой кнопки мыши на строке таблицы она (переменная) выделяется. Несколько строк (переменных) выделяются щелчком левой кнопки мыши на каждой строке при удержании клавиши <Ctrl>.

        Контекстное меню


          Щелчком правой кнопки мыши на панели «Переменные окружения» открывается контекстное меню:
        • «Новая переменная. » - открывается окно «Новая переменная» (рис. 6):
        • «Переменная» - в строке ввода или из выпадающего списка устанавливается переменная окружения. Переменные в списке:
          • DISPLAY - номер дисплея, на котором запускается графическая оболочка ОС;
          • LANG - локаль, с которой выполняется задача;
          • PATH - каталоги поиска программ;
          • HOME - домашний каталог пользователя;
          • MAILTO - имя пользователя, которому будет отправлено письмо, содержащее отчет о запуске задачи;
          • SHELL - интерпретатор команд, внутри которого будет запущена назначенная задача;
          • LD_CONGIG_PATH - дополнительные (помимо системных) каталоги поиска разделяемых библиотек;
          • [Да] - выделенные переменные удаляются из списка переменных окружения, из таблицы удаляются выделенные строки, и окно закрывается;
          • [Нет] - окно закрывается.

          Кнопки сопровождения

          Кнопки сопровождения располагаются справа от панели «Переменные окружения» (см. рис. 1) и повторяют аналогичные пункты контекстного меню (см. Контекстное меню): [Новая переменная. ], [Правка. ], [Удалить].

          Планировщик заданий является по праву одним из важных компонентов системы. По умолчанию, в дистрибутивах Linux, а также FreeBSD, используется планировщик заданий Cron. Рассмотрим как его настроить.

          Настроить cron можно несколькими способами. Самый простой и быстрый - указать задание руками в файл /etc/crontab. Проблема в том, что это может сделать только пользователь root.

          Структура файла /etc/crontab представляет собой последовательность установок даты и времени, имени пользователя от которого выполняется задача и явное указание исполняемого файла.

          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.

          На что еще следует обратить внимание:

          Все пути до исполняемых файлов следует писать абсолютными.

          Скрипты исполняются из корневой директории, а следовательно, при написании скрипта следует указывать рабочий каталог, либо абсолютные пути до целевых файлов (если в ходе работы скрипта генерируются файлы-отчета и им подобные)



          Классик писал, что счастливые часов не наблюдают. В те дикие времена ещё не было ни программистов, ни 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.

          Если оригинальный 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 и пользователи без доступа к программе. Расположение этих файлов стандарт никак не регламентирует.

          Запускаемым программам, согласно стандарту, должны передаваться по меньшей мере четыре переменные окружения:

          1. HOME — домашняя директория пользователя.
          2. LOGNAME — логин пользователя.
          3. PATH — путь, по которому можно найти стандартные утилиты системы.
          4. SHELL — путь к использованному командному интерпретатору.

          Примечательно, что POSIX ничего не говорит о том, откуда берутся значения для этих переменных.

          Общий предок популярных вариантов 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).

          Разработчики 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 — форк 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-совместимом режиме и не читает никакой дополнительной конфигурации, работая в неинтерактивном режиме.

          Немецкий дистрибутив SLES и его дериватив openSUSE используют всё тот же cronie. Демон здесь тоже запускается под systemd, конфигурация сервиса лежит в /usr/lib/systemd/system/cron.service. Конфигурация: /etc/crontab, /etc/cron.d, /var/spool/cron/tabs. В качестве /bin/sh выступает тот же самый bash, запущенный в POSIX-совместимом неинтерактивном режиме.

          Современные потомки cron по сравнению с Vixie cron не изменились радикально, но всё же обзавелись новыми возможностями, не требующимися для понимания принципов работы программы. Многие из этих расширений оформлены неаккуратно и путают код. Оригинальный же исходный код cron в исполнении Пола Викси читать одно удовольствие.

          Поэтому разбор устройства cron я решил провести на примере общей для обеих ветвей развития cron программы — Vixie cron 3.0pl1. Примеры я упрощу, убрав усложняющие чтение ifdef-ы и опустив второстепенные детали.

          Работу демона можно разделить на несколько этапов:

          1. Инициализация программы.
          2. Сбор и обновление списка задач для запуска.
          3. Работа главного цикла cron.
          4. Запуск задачи.

          Разберём их по порядку.

          Инициализация

          При запуске после проверки аргументов процесса 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, используйте простые программы и не забывайте читать маны для вашей платформы!

          Читайте также: