Перейти к содержанию

13.3 Планирование запуска процессов (Scheduling Process Execution)

До сих пор в этой главе вы учились запускать процессы и управлять ими из командной строки. Однако нередко возникает необходимость в автоматическом запуске процесса без какого-либо вмешательства с вашей стороны. Хороший пример — резервное копирование. Основная проблема с резервными копиями состоит не в том, что системные администраторы делают их неправильно: они попросту забывают их делать! Одна из худших ошибок в стратегии резервного копирования — надеяться на то, что человек не забудет запустить соответствующую процедуру.

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

  • использование демона at;
  • использование демона cron;
  • использование anacron.

Начнём с изучения демона at.

Использование демона at (Using the at Daemon)

at — удобный инструмент для однократного планирования запуска процесса в будущем. Служба at — это системный демон (daemon) с именем atd, работающий в фоновом режиме. Большинство дистрибутивов Linux устанавливают эту службу автоматически при первоначальной установке системы. Если нет — потребуется установить её вручную из репозитория с помощью утилиты rpm.

Если в вашем дистрибутиве используется init, то сценарий запуска демона atd находится в каталоге init-сценариев — /etc/init.d или /etc/rc.d/init.d, в зависимости от дистрибутива. Имя сценария — atd.

Прежде чем использовать at, убедитесь, что демон atd запущен. Для этого выполните в командной строке rcatd start. Можно также запустить файл сценария с его полным путём, добавив start в конце команды. Чтобы демон atd запускался автоматически при загрузке, воспользуйтесь командой insserv или chkconfig.

Если в вашем дистрибутиве используется systemd, запустите демон atd командой systemctl start atd от имени суперпользователя root.

Далее необходимо указать, какие пользователи могут, а какие не могут создавать задания at. Это делается редактированием следующих файлов:

  • /etc/at.allow — пользователи, перечисленные в этом файле, имеют право создавать задания at.
  • /etc/at.deny — пользователи, перечисленные в этом файле, не имеют права создавать задания at.

Чтобы запланировать выполнение команды с помощью at, выполните следующие шаги.

1. В командной строке введите at время. Демон at достаточно гибко интерпретирует значение времени. Допустимый синтаксис приведён в таблице 13-2.

Тип ссылки Синтаксис Описание
Фиксированное HH:MM Точный час и минута выполнения команды. Демон at считает, что указанное время относится к сегодняшнему дню, если оно ещё не прошло; иначе — к завтрашнему. Можно добавить am или pm для указания утреннего или дневного времени.
Noon Команда выполняется в 12:00.
Midnight Команда выполняется в 0:00.
Teatime Команда выполняется в 16:00.
MMDDYY или MM/DD/YY или MM.DD.YY Точный месяц, день и год выполнения команды.
HH:MM MMDDYY Точный месяц, день, год и время выполнения команды.
Относительное now Команда выполняется немедленно.
now + значение Команда выполняется через указанное время в будущем. Например: now + 5 minutes, now + 2 hours, now + 3 days.
today Команда выполняется сегодня. Можно комбинировать с фиксированным значением: 2 pm today.
tomorrow Команда выполняется завтра. Можно комбинировать с фиксированным значением: 2 pm tomorrow.

Таблица 13-2. Синтаксис задания времени в команде at

После ввода команды at со значением времени из таблицы 13-2 на экране появляется приглашение at>:

openSUSE:~ # at now +10 minutes
warning: commands will be executed using /bin/sh
at>

2. В строке приглашения at> введите команду (или команды), которые должны выполниться. Важно учитывать: если ваши команды выводят что-либо на экран при запуске из командной строки, при выполнении через at вы этот вывод не увидите. Существуют два способа получить вывод. По умолчанию, если не указать ни одной альтернативы, at отправит вывод на вашу локальную учётную запись по электронной почте.

Кроме того, вывод можно перенаправить в файл. Например, если вы хотите запустить команду tail /var/log/messages в будущем через at, в приглашении at> введите tail /var/log/messages > ~/atoutput.txt, чтобы направить вывод в текстовый файл atoutput.txt в вашем домашнем каталоге.

3. Нажмите ENTER для добавления дополнительных команд. В одном задании может выполняться несколько команд — каждая на отдельной строке.

4. Завершив ввод команд, нажмите CTRL-D. Приглашение at> исчезнет, задание будет запланировано, и ему будет присвоен номер:

openSUSE:~ # at now +10 minutes
warning: commands will be executed using /bin/sh
at> tail /var/log/messages > ~/atoutput.txt
at> <EOT>
job 3 at 2011-04-02 08:57
openSUSE:~ #

После настройки задания для просмотра списка ожидающих заданий at можно использовать команду atq:

openSUSE:~ # atq
3       2011-04-02 08:57 a root

Если вы вошли в систему как обычный пользователь, atq отобразит только задания, связанные с текущей учётной записью. Если вы работаете под учётной записью root, atq покажет все ожидающие задания для всех пользователей. Чтобы удалить ожидающее задание из списка, используйте команду atrm номер_задания.

Помимо демона at, для планирования будущих заданий можно использовать демон cron. Рассмотрим, как это делается.

Использование демона cron (Using the cron Daemon)

Демон at удобен, однако имеет один существенный недостаток: он может запланировать задание лишь на однократное выполнение в будущем. Это не проблема, если вам нужен разовый запуск. Но нередко возникает необходимость запускать задание регулярно по расписанию: например, ежедневно в определённое время выполнять резервное копирование. В такой ситуации at не подходит — нужен инструмент, способный обрабатывать повторяющиеся расписания.

С этим справляется демон cron. В отличие от at, cron позволяет выполнять команды по расписанию, которое вы сами задаёте. Это очень мощный и полезный сервис. at я использую от случая к случаю, тогда как cron — постоянно. Без него мне было бы сложно справляться с работой. Большинство офисов клиентов находятся далеко от моего офиса, и объезжать их каждый день ради резервного копирования не представляется возможным. Разумеется, я не доверяю административному персоналу клиентов проверять, выполняется ли резервное копирование каждый день. Вместо этого я настраиваю демон cron на запуск резервного копирования автоматически. Так я знаю, что оно выполняется по расписанию и нужная команда при этом отдаётся.

В этой части главы мы рассмотрим:

  • как работает cron;
  • использование cron для управления запланированными системными заданиями;
  • использование cron для управления пользовательскими заданиями.

Начнём с изучения работы службы cron.

Как работает cron (How cron Works)

Демон cron — это служба, непрерывно работающая в фоновом режиме и каждую минуту проверяющая специальный файл, называемый файлом crontab (crontab file), в поисках запланированных заданий. Если в вашем дистрибутиве используется init, демон cron управляется сценарием cron в каталоге init. Если используется systemd — для управления демоном cron применяется команда systemctl.

По умолчанию демон cron настроен на автоматический запуск при каждой загрузке системы в большинстве дистрибутивов Linux. Если это не так — потребуется запустить его вручную с помощью сценария cron в каталоге init вашей системы.

Для cron можно настроить выполнение как системных, так и пользовательских заданий. Начнём с системных.

Использование cron для управления запланированными системными заданиями (Using cron to Manage Scheduled System Jobs)

Использование cron для запланированных системных заданий — чрезвычайно удобный инструмент в арсенале администратора Linux. Вы можете автоматически выполнять широкий спектр задач по расписанию, экономя массу времени и усилий.

Для выполнения системных заданий служба cron использует файл /etc/crontab, в котором настраивается, какие задания и когда запускать:

openSUSE:/etc # cat ./crontab
SHELL=/bin/sh
PATH=/usr/bin:/usr/sbin:/sbin:/bin:/usr/lib/news/bin
MAILTO=root
#
# check scripts in cron.hourly, cron.daily, cron.weekly, and cron.monthly
#
-*/15 * * * *   root test -x /usr/lib/cron/run-crons &&
/usr/lib/cron/run-crons >/dev/null 2>&1

Как видно из этого примера, файл /etc/crontab содержит команды для запуска сценариев из четырёх разных каталогов:

  • /etc/cron.hourly — содержит cron-сценарии, запускаемые каждый час;
  • /etc/cron.daily — содержит cron-сценарии, запускаемые каждый день;
  • /etc/cron.weekly — содержит cron-сценарии, запускаемые раз в неделю;
  • /etc/cron.monthly — содержит cron-сценарии, запускаемые раз в месяц.

Все сценарии, находящиеся в любом из этих каталогов, автоматически запускаются cron согласно заданному расписанию. Например, в каталоге /etc/cron.daily хранится ряд сценариев для очистки системы и ротации журналов, выполняемых раз в день:

openSUSE:/etc/cron.daily # ls
logrotate                   suse-clean_catman                               suse.de-backup-rpmdb
mdadm                       suse-do_mandb                                   suse.de-check-battery
packagekit-background.cron suse.de-backup-rc.config                         suse.de-cron-local

Если у вас есть системное задание, которое должно выполняться по одному из этих четырёх расписаний, достаточно создать файл сценария и скопировать его в соответствующий каталог cron в /etc.

Что делать, если задание должно выполняться по расписанию, не совпадающему ни с одним из четырёх стандартных? Не проблема. Помимо четырёх каталогов, описанных выше, в /etc/ есть пятый — cron.d.

Для выполнения системного задания по нестандартному расписанию создайте файл crontab в этом каталоге — демон cron прочитает и запустит его.

Как создать файл crontab? Это выглядит сложно, но на самом деле нет. Файл crontab — это просто текстовый файл, в котором каждая строка описывает одно задание. Каждая строка содержит шесть полей, разделённых знаками табуляции, как показано в таблице 13-3.

Поле Описание
1 Минуты. Количество минут после начала часа, когда должна выполниться команда.
2 Час. Час суток, когда должна выполниться команда. Демон cron предпочитает военное время, поэтому используйте значения от 0 до 23.
3 День. День месяца, когда должна выполниться команда.
4 Месяц. Месяц года, когда должна выполниться команда.
5 День недели. Воскресенье — 0, суббота — 6.
6 Имя команды с полным путём.

Таблица 13-3. Поля файла crontab

Во многих строках файла crontab можно встретить символ звёздочки (*) в одном или нескольких полях. Этот подстановочный знак означает «совпадать с любым значением».

Например, чтобы запустить команду tar для резервного копирования каталога /home с помощью tar –cvf /media/usb/backup.tar /home каждый день каждого месяца, кроме воскресений, в 23:05, в файл /etc/crontab.d можно добавить следующую строку:

5       23       *         *     1-6      /bin/tar -cvf /media/usb/backup.tar /home

Эта строка предписывает выполнять команду через 5 минут после 23:00 (23) каждый день (*) каждого месяца (*) с понедельника (1) по субботу (6).

Примечание

Системные задания cron выполняются от имени суперпользователя root!

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

Использование cron для управления пользовательскими заданиями (Using cron to Manage Scheduled User Jobs)

Пользователи системы могут создавать собственные расписания, используя файл crontab, связанный с их учётной записью. В отличие от системных файлов crontab, хранящихся в /etc, пользовательские файлы crontab находятся в /var/spool/cron/tabs. Если пользователь создал файл crontab, он сохраняется там под его именем пользователя.

Следует сразу оговориться, что не все системные администраторы разрешают пользователям создавать собственные файлы crontab. Если это вас беспокоит, вы можете запретить пользователям создавать их. Для этого применяется подход, аналогичный используемому при работе с демоном at.

При запуске демон cron читает файлы /etc/cron.allow и /etc/cron.deny, чтобы определить, кто может, а кто не может создавать расписания в crontab. По умолчанию автоматически создаётся только файл /etc/cron.deny, содержащий единственное ограничение — для учётной записи гостя. Все остальные пользователи могут создавать файлы crontab. Если создать файл /etc/cron.allow, создавать файлы crontab смогут только пользователи, перечисленные в нём; остальным будет отказано.

Чтобы создать собственный файл crontab, пользователь может воспользоваться командой crontab –e. После её выполнения в редакторе vi откроется новый пустой файл crontab.

В этом файле пользователь добавляет строки для каждого задания в соответствии с синтаксисом, описанным выше. Например, на рис. 13-13 команда tar выполняется в 17:10 каждый день для резервного копирования домашнего каталога пользователя в файл ~/homebak.tar.

Файл редактируется стандартными командами и клавишами vi, с которыми вы познакомились ранее. Завершив редактирование, выйдите из vi и сохраните файл. После этого новый файл crontab пользователя будет создан в /var/spool/cron/tabs:

Рис. 13-13. Создание пользовательского файла crontab.

Рис. 13-13. Создание пользовательского файла crontab.

openSUSE:/ # ls /var/spool/cron/tabs/
rtracy
openSUSE:/ # cat /var/spool/cron/tabs/rtracy
# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (/tmp/crontab.wwzr9t installed on Tue Dec 2 22:31:44 2014)
# (Cronie version 4.2)
10      17      *       *       *       /bin/tar -cvf ~/homebak.tar ~

В данном примере я использовал команду cat для просмотра файла crontab пользователя tux. Однако для отображения файла crontab текущего пользователя можно воспользоваться командой crontab –l. Для удаления файла crontab пользователя используйте команду crontab –r.

Потренируемся работать с процессами Linux в следующем упражнении.

Упражнение 13-2. Планирование выполнения процессов Linux

В этом упражнении вы потренируетесь использовать команды cron и at для планирования запуска процессов в будущем. Для выполнения упражнения можно использовать виртуальную машину, поставляемую с этой книгой. Запустите снимок состояния 13-2 для правильно настроенной среды.

Выполните следующие шаги:

  1. Загрузите систему Linux и войдите под обычным пользователем.
  2. Откройте сеанс терминала.
  3. Переключитесь на учётную запись root, введя su – и пароль student.
  4. Отработайте использование демона at:
    • a. В командной строке введите systemctl status atd.
    • b. Убедитесь, что демон at запущен. Если нет — введите systemctl start atd.
    • c. В командной строке введите at now +5 minutes.
    • d. В приглашении at введите ps –ef > ~/psoutput.txt.
    • e. Нажмите CTRL-D.
    • f. Выведите список ожидающих заданий at, введя atq. Вы должны увидеть только что созданное задание.
    • g. Дождитесь выполнения ожидающего задания at.
    • h. Используйте команду cat для проверки файла ~/psoutput.txt и убедитесь, что вывод команды ps был сформирован корректно.
    • i. В командной строке введите at 2 pm tomorrow.
    • j. В приглашении at введите ps –ef > ~/psoutput.txt.
    • k. Нажмите ENTER.
    • l. Нажмите CTRL-D.
    • m. Выведите список ожидающих заданий at, введя atq. Вы должны увидеть только что созданное задание. Запомните его номер.
    • n. Удалите ожидающее задание командой atrm номер_задания.
    • o. Введите atq снова. Ожидающее задание должно исчезнуть.
  5. Отработайте использование cron:
    • a. Выйдите из учётной записи root, введя exit.
    • b. В командной строке введите crontab –e.
    • c. Нажмите INSERT.
    • d. Настройте резервное копирование домашнего каталога вашего пользователя каждый день в 17:05, введя следующую строку:
      05       17      *      *       *       /bin/tar –cvf ~/mybackup.tar ~/
      
      Если ждать до 17:05 не хочется, можно указать время на два-три минуты вперёд от текущего.
    • e. Нажмите ESC.
    • f. Введите :exit. На экране должно появиться сообщение о том, что новый crontab установлен.
    • g. Введите crontab –l и убедитесь, что задание создано правильно.
    • h. Дождитесь времени, указанного в файле crontab, затем проверьте домашний каталог пользователя и убедитесь, что файл mybackup.tar был создан.
    • i. Удалите файл crontab пользователя, введя crontab –r в командной строке.

Использование anacron (Using anacron)

Некоторые дистрибутивы используют anacron совместно с cron для автоматизации выполнения задач. Обе службы работают практически одинаково. Ключевое отличие в том, что cron предполагает, что компьютер работает 24 часа в сутки, 7 дней в неделю. Это подходит для серверов и настольных компьютеров, но не для всех систем. Например, ноутбук вполне может быть выключен или находиться в спящем режиме в определённые периоды суток. Если система выключена в момент, когда по расписанию cron должно выполниться задание, оно пропускается.

Служба anacron (anacron) призвана решить эту проблему. Если задание запланировано в anacron, но система была выключена, пропущенное задание автоматически выполнится при следующем запуске системы.

Подобно тому как cron использует файл /etc/crontab, anacron использует файл /etc/anacrontab. Этот файл содержит следующие поля:

period     delay        job-identifier        command

Первое поле задаёт период повторения (в днях). Например, можно использовать одно из следующих значений:

  • 1 — задание выполняется ежедневно;
  • 7 — задание выполняется еженедельно;
  • 30 — задание выполняется ежемесячно.

Второе поле задаёт задержку (в минутах), которую anacron выдержит перед выполнением пропущенного задания после запуска системы.

Третье поле содержит идентификатор задания (job identifier). Это имя, которое будет использоваться для файла метки времени задания; оно должно быть уникальным для каждого задания anacron. Файл создаётся в каталоге /var/spool/anacron и содержит единственную строку с меткой времени последнего выполнения данного задания. Четвёртое поле задаёт выполняемую команду или сценарий.

Рассмотрим следующий пример, в котором anacron настроен на ежедневный запуск сценария /usr/bin/updatedb.sh. Если система была выключена в момент предполагаемого запуска, сценарий выполнится через 30 минут после следующего запуска системы:

openSUSE:/ # cat /etc/anacrontab
1       30      updatedbtime.log                  /usr/bin/updatedb.sh

Обратите внимание, что в этом файле не указывается точное время запуска задания. Оно настраивается переменной START_HOURS_RANGE в файле /etc/anacrontab. В следующем примере диапазон запуска установлен равным 3-22, то есть с 3:00 до 22:00:

openSUSE# cat /etc/anacrontab
...
START_HOURS_RANGE=3-22

Важно также учитывать, что anacron добавляет случайное количество минут к значению, указанному во втором поле файла anacrontab. Максимальное количество добавляемых минут определяется переменной RANDOM_DELAY в файле /etc/anacrontab. По умолчанию эта переменная равна 45, что означает добавление случайного числа минут от 0 до 45 к значению задержки в anacrontab:

openSUSE# cat /etc/anacrontab
...
RANDOM_DELAY=45

Отлично! Теперь вы знаете, как управлять процессами Linux в вашей системе. Немного кто может этим похвастаться. Перейдём к обзору того, что вы узнали в этой главе.