Рубрики
Без рубрики

Планирование заданий с помощью python-crontab

Автор оригинала: Scott Robinson.

Что такое Кронтаб

Cron-это программная утилита, которая позволяет нам планировать задачи в Unix-подобных системах. Название происходит от греческого слова “Хронос”, что означает “время”.

Задачи в Cron определяются в crontab, который представляет собой текстовый файл, содержащий команды, которые должны быть выполнены. Синтаксис, используемый в crontab, описан ниже в этой статье.

Python представляет нам модуль crontab для управления запланированными заданиями через Cron. Доступные в нем функции позволяют нам получать доступ к Cron, создавать задания, устанавливать ограничения, удалять задания и многое другое. В этой статье мы покажем, как использовать эти операции из вашего кода Python.

Для заинтересованного читателя официальную страницу справки можно найти по адресу https://pypi.python.org/pypi/python-crontab .

Синтаксис Crontab

Cron использует определенный синтаксис для определения временных расписаний. Он состоит из пяти полей, разделенных пробелами. Поля такие:

Minute Hour Day Month Day_of_the_Week

Поля могут иметь следующие значения:

┌───────────── minute (0 - 59)
│ ┌───────────── hour (0 - 23) 
│ │ ┌───────────── day of month (1 - 31)
│ │ │ ┌───────────── month (1 - 12)
│ │ │ │ ┌───────────── day of week (0 - 6) (Sunday to Saturday;
│ │ │ │ │                                       7 is also Sunday on some systems)
│ │ │ │ │
│ │ │ │ │
* * * * *  command to execute

Источник: Википедия. Крон. Доступно по адресу Источник: Википедия. Крон. Доступно по адресу

Cron также принимает специальные символы, так что вы можете создавать более сложные расписания. Специальные символы имеют следующие значения:

Для разделения нескольких значений Запятая
Для указания диапазона значений Дефис
Чтобы указать все возможные значения Звездочка
Чтобы указать КАЖДЫЙ Косая черта вперед

Давайте рассмотрим несколько примеров:

  1. * * * * * означает: каждую минуту каждого часа каждого дня месяца за каждый месяц за каждый день недели.
  2. 0 16 1,10,22 * * говорит cron запускать задачу в 4 часа дня (то есть 16-го часа) 1-го, 10-го и 22-го числа каждого месяца.

Установка Crontab

Crontab не входит в стандартную установку Python. Таким образом, первое, что мы должны сделать, это установить его.

Это делается с помощью команды pip . Единственное, что следует учитывать, это то, что имя модуля- “python-crontab”, а не просто “crontab”. Следующая команда установит пакет в нашу машину:

$ pip install python-crontab

Получение доступа к Crontab

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

Первый способ получить доступ к cron-это использовать имя пользователя. Синтаксис выглядит следующим образом:

cron = CronTab(user='username')

Другими двумя способами Linux являются:

cron = CronTab()

# or

cron = CronTab(user=True)

Есть еще два синтаксиса, которые также будут работать в Windows.

В первом случае мы вызываем задачу, определенную в файле “filename.tab”:

cron = CronTab(tabfile='filename.tab')

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

cron = CronTab(tab="""* * * * * command""")

Создание новой работы

Получив доступ к cron, мы можем создать новую задачу с помощью следующей команды:

cron.new(command='my command')

Здесь my command определяет задачу, которая будет выполняться через командную строку.

Мы также можем добавить комментарий к нашей задаче. Синтаксис выглядит следующим образом:

cron.new(command='my command', comment='my comment')

Давайте рассмотрим это на примере:

from crontab import CronTab

cron = CronTab(user='username')
job = cron.new(command='python example1.py')
job.minute.every(1)

cron.write()

В приведенном выше коде мы сначала получили доступ к cron через имя пользователя, а затем создали задание, которое состоит из запуска скрипта Python с именем example1.py. Кроме того, мы поставили задачу запускаться каждые 1 минуту. Функция write() добавляет нашу работу в cron.

В example1.py сценарий выглядит следующим образом:

from datetime import datetime
myFile = open('append.txt', 'a') 
myFile.write('\nAccessed on ' + str(datetime.now()))

Как мы видим из приведенного выше кода, программа откроет и добавит фразу “Доступ включен” с добавлением даты и времени доступа.

В результате получается следующее:

append.txt файл

Рисунок 1

Как мы и ожидали, Рисунок 1 показывает, что файл был доступен программой. Он будет продолжать выполнять поставленную задачу, пока example1.py программа работает на cron.

Как только cron будет доступен, мы сможем добавить более одного задания. Например следующая строка в приведенном выше примере добавит вторую задачу для управления cron:

job2 = cron.new(command='python example2.py')

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

Установка ограничений

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

В приведенном выше примере мы уже видели, как настроить выполнение задания каждую минуту. Синтаксис выглядит следующим образом:

job.minute.every(minutes)

Точно так же мы могли бы установить часы:

job.hour.every(hours)

Мы также можем настроить задачу на выполнение в определенные дни недели. Например:

job.dow.on('SUN')

Приведенный выше код скажет cron запускать задачу по воскресеньям, а следующий код скажет cron планировать задачу по воскресеньям и пятницам:

job.dow.on('SUN', 'FRI')

Точно так же мы можем сказать cron, чтобы он выполнял задачу в определенные месяцы. Например:

job.month.during('APR', 'NOV')

Это подскажет крону запустить программу в апреле и ноябре.

Важно учитывать, что каждый раз, когда мы устанавливаем ограничение по времени, мы аннулируем предыдущее. Так, например:

job.hour.every(5)
job.hour.every(7)

Приведенный выше код установит окончательное расписание для запуска каждые семь часов, отменяя предыдущее расписание в пять часов.

Если только мы не добавим расписание к предыдущему, как это:

job.hour.every(15)
job.hour.also.on(3)

Это установит расписание как каждые 15 часов, и в 3 часа ночи.

“Каждое” условие иногда может быть немного запутанным. Если мы напишем job.hour.every(15) , то это будет эквивалентно * */15 * * * . Как мы видим, протокол не был изменен.

Если мы хотим установить поле минут равным нулю, мы можем использовать следующий синтаксис:

job.every(15).hours()

Это установит расписание на 0 */4 * * * . Аналогично для полей “день месяца”, “месяц” и “день недели”.

Примеры:

  1. job.every(2).month эквивалентен 0 0 0 */2 * и job.month.every(2) эквивалентно * * * */2 *
  2. job.every(2).down эквивалентен 0 0 * * */2 и job.down.every(2) эквивалентно * * * * */2

Различия можно увидеть в следующем примере:

from crontab import CronTab

cron = CronTab(user='username')

job1 = cron.new(command='python example1.py')

job1.hour.every(2)

job2 = cron.new(command='python example1.py')
job2.every(2).hours()

for item in cron:
    print item

cron.write()

После запуска программы результат выглядит следующим образом:

$ python cron2.py
* */2 * * * python /home/eca/cron/example1.py
0 */2 * * * python /home/eca/cron/example1.py
$

Рисунок 2

Как мы видим на рис.2 , программа установила минуты второй задачи равными нулю, а минуты первой задачи-значению по умолчанию.

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

job.every_reboot()

Клиринговые ограничения

Мы можем снять все ограничения задачи с помощью следующей команды:

job.clear()

Следующий код показывает, как использовать приведенную выше команду:

from crontab import CronTab

cron = CronTab(user='username')

job = cron.new(command='python example1.py', comment='comment')
job.minute.every(5)

for item in cron:
    print item

job.clear()

for item in cron:
    print item
cron.write()

После запуска кода мы получаем следующий результат:

$ python cron3.py
*/5 * * * * python /home/eca/cron/example1.py # comment
* * * * * python /home/eca/cron/example1.py # comment

Рисунок 3

Как мы видим на рис. 3, расписание изменилось с каждых 5 минут на значение по умолчанию.

Включение и выключение задания

Задачу можно включить или отключить с помощью следующих команд:

Чтобы включить задание:

job.enable()

Чтобы отключить задание:

job.enable(False)

Чтобы проверить, включена или отключена задача, мы можем использовать следующую команду:

job.is_enabled()

В следующем примере показано, как включить и отключить ранее созданное задание, а также проверить оба состояния:

from crontab import CronTab

cron = CronTab(user='username')

job = cron.new(command='python example1.py', comment='comment')
job.minute.every(1)

cron.write()

print job.enable()
print job.enable(False)

В результате получается следующее:

$ python cron4.py
True
False

Рисунок 4

Проверка валидности

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

job.is_valid()

В следующем примере показано, как использовать эту команду:

from crontab import CronTab

cron = CronTab(user='username')

job = cron.new(command='python example1.py', comment='comment')
job.minute.every(1)

cron.write()

print job.is_valid()

После запуска вышеуказанной программы мы получаем проверку, как показано на следующем рисунке:

$ python cron5.py
True

Рисунок 5

Список Всех Заданий Cron

Все задания cron, включая отключенные задания, могут быть перечислены со следующим кодом:

for job in cron:
    print job

Добавление этих строк кода в наш первый пример покажет нашу задачу, напечатав на экране следующее:

$ python cron6.py
* * * * * python /home/eca/cron/example1.py

Рисунок 6

Поиск работы

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

Найти по команде:

cron.find_command("command name")

Здесь “имя команды” может быть суб-совпадением или регулярным выражением.

Найти по комментарию:

cron.find_comment("comment")

Найти по времени:

cron.find_time(time schedule)

В следующем примере показано, как найти ранее определенную задачу в соответствии с тремя ранее упомянутыми критериями:

from crontab import CronTab

cron = CronTab(user='username')

job = cron.new(command='python example1.py', comment='comment')
job.minute.every(1)

cron.write()

iter1 = cron.find_command('exam')
iter2 = cron.find_comment('comment')
iter3 = cron.find_time("*/1 * * * *")

for item1 in iter1:
    print item1

for item2 in iter2:
    print item2

for item3 in iter3:
    print item3

Результатом является перечисление одной и той же работы три раза:

$ python cron7.py
* * * * * python /home/eca/cron/example1.py # comment
* * * * * python /home/eca/cron/example1.py # comment
* * * * * python /home/eca/cron/example1.py # comment

Рисунок 7

Как вы можете видеть, он каждый раз правильно находит команду cron.

Удаление заданий

Каждое задание может быть удалено отдельно. Синтаксис выглядит следующим образом:

cron.remove(job)

В следующем коде показано, как удалить ранее созданную задачу. Программа сначала создает задачу. Затем он перечисляет все задачи, показывая только что созданную. После этого он удаляет задачу и показывает полученный пустой список.

from crontab import CronTab

cron = CronTab(user='username')

job = cron.new(command='python example1.py')
job.minute.every(1)

cron.write()
print "Job created"

# list all cron jobs (including disabled ones)
for job in cron:
    print job

cron.remove(job)
print "Job removed"

# list all cron jobs (including disabled ones)
for job in cron:
    print job

В результате получается следующее:

$ python cron8.py
Job created
* * * * * python /home/eca/cron/example1.py
Job removed

Рисунок 8

Задания также могут быть удалены в зависимости от условия. Например:

cron.remove_all(comment='my comment')

Это приведет к удалению всех заданий, где comment='my comment' .

Очистка Всех Заданий

Все задания cron можно удалить сразу с помощью следующей команды:

cron.remove_all()

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

from crontab import CronTab

cron = CronTab(user='username')
cron.remove_all()

# list all cron jobs (including disabled ones)
for job in cron:
    print job

Переменные среды

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

job.env['VARIABLE_NAME'] = 'Value'

Если мы хотим получить значения для всех переменных среды, мы можем использовать следующий синтаксис:

job.env

В приведенном ниже примере определены две новые переменные среды для задачи “пользователь” и показано их значение на экране. Код выглядит следующим образом:

from crontab import CronTab

cron = CronTab(user='username')

job = cron.new(command='python example1.py')
job.minute.every(1)
job.env['MY_ENV1'] = 'A'
job.env['MY_ENV2'] = 'B'

cron.write()

print job.env

Запустив вышеописанную программу, мы получим следующий результат:

$ python cron9.py
MY_ENV1=A
MY_ENV2=B

Рисунок 9

Кроме того, переменные среды уровня Cron хранятся в файле ‘cron.env’.

Сворачивание

Модуль Python crontab предоставляет нам удобный инструмент для программного управления нашим приложением carbon, которое доступно для Unix-подобных систем. Используя его, вместо того, чтобы полагаться на создание кронтабов, мы можем использовать код Python для управления частыми задачами.

Модуль вполне закончен. Несмотря на некоторые критические замечания по поводу его поведения, он содержит функции для подключения к cron, создания запланированных задач и управления ими. Как показано в приведенных выше примерах, их использование достаточно прямолинейно. Таким образом, он предоставляет инструмент, который позволяет создавать сложные скрипты с основной характеристикой Python: простотой.