Журнал LinuxFormat - перейти на главную

LXF95:Cron

Материал из Linuxformat
Перейти к: навигация, поиск

Содержание

Часть 1: Осваиваем Cron

    Ежедневное задание Cron поможет вам выполнить работу, отдохнуть и поиграть. Д-р Крис Браун покажет, как настроить crontab’ы и применить Anacron, чтобы ваша система работала, как часы.

    Как у вас с греческим? Вы знаете, что [chronos, хронос] означает «время»? Конечно, знаете! А в греческой мифологии Хронос был богом и воплощением времени. Поэтому у нас есть такие слова, как хронометр и хронология. Программисты никогда не славились своим правописанием, поэтому сервис Linux, который запускает определенные команды в указанное время, назван Cron.
    На нашем уроке вы изучите, как настроить Cron, чтобы планировать собственные задачи, и разберетесь с настройкой файла конфигурации Cron, поставляемого с вашим дистрибутивом Linux. Cron превосходен для машин, запущенных на постоянную работу, но во второй части урока мы рассмотрим его младшего братца Anacron, более подходящего для персональных компьютеров, которые часть времени проводят выключенными.
    Cron существует уже довольно давно (хотя и не так давно, как Хронос). Даже в моем потрепанном руководстве шестой редакции Unix, датированном 1974 г., есть упоминание о нем. С тех пор он несколько раз переписывался, и версия, которая в настоящий момент присутствует в Linux-дистрибутивах обычно известна как Vixie Cron, написанная Полом Викси [Paul Vixie].
    Проще говоря, Cron – это демон, запускающий определенные команды в определенное время дня и/или определенные дни недели. Он ежеминутно просыпается и просматривает свои файлы настройки – известные как crontab’ы [таблицы cron] – в поисках назначенных заданий на текущую минуту. Если задание найдено, оно выполняется. Затем программа снова на минуту засыпает. Cron обычно стартует во время загрузки.

    Мы используем Cron для планирования различных заданий; некоторые примеры приведены во врезке Где пригодится Cron, ниже. Большинство дистрибутивов Linux поставляют Cron уже настроенным на выполнение некоторых задач, но добавить свои вовсе не сложно, если знаешь как. Люди проделывают с Cron невероятные вещи. Мой коллега однажды написал скрипт, собирающий статистику о занятости машины. Используя Cron, он запускал скрипт каждые 0, 15, 30 и 45 минут от начала каждого часа и отправлял результаты на центральную машину. Другой скрипт Cron запускал каждые 5, 20, 35 и 50 минут от начала каждого часа на центральной машине, чтоб обработать статистику, а затем предоставить ее в виде HTML-отчетов для инженеров и менеджеров. Он также создавал графики нагрузки на машины в зависимости от времени дня.
    Другой мой коллега использовал Cron для скачивания спутниковых изображений из бюро погоды; он делал это пару лет, а затем свел их вместе и получил кино. Я знаю менеджера, который при помощи Cron отключал права на запуск всех игр в 9:00 каждое утро и затем восстанавливал их вечером; а один родитель употребил его для блокировки входа в Интернет (с помощью iptables) каждый вечер, чтобы дети не лазили по Сети всю ночь, а наутро восстанавливал доступ.
    О том, что и когда делать, Cron узнает из набора файлов, называемых crontab’ами. Прежде всего, есть /etc/crontab, иногда называемый системным crontab’ом. Анатомия одной записи в этом файле показана на диаграмме напротив. В каждое из пяти временных полей вы можете поместить:

  • означающую любое значение.
  • одиночное значение.
  • Список значений, разделённых запятыми, например, 15, 25, 40.
  • Диапазон, например 9-18.
  • Период; обычно следует за *. Например, */5 в поле минуты будет означать «каждые пять минут». Вот несколько примеров:
*/10 * * 5,7,11 * root command1
0 9-18 * * 1-5 root command2 

    Первая строка показывает, что command1 будет запускаться каждые 10 минут в мае, июле и ноябре, а command2 – раз в час во время рабочего дня (с 9 до 18) с понедельника по пятницу. Видите, какая гибкая система! Между прочим, шестое поле в записи crontab, где в наших примерах стоит root, определяет идентификатор пользователя, под которым будет запущена программа. Вы почти всегда будете видеть root в этом поле, пока осторожный администратор не воспользуется принципом наименьших привилегий и не выберет пользователя с минимально необходимыми для запуска программы правами.
    Хотя вполне дозволено запускать программы прямо из crontab, сейчас в Linux-дистрибутивах пошла мода на промежуточный скрипт, обычно называемый run-parts. Например, вот системный crontab из Red Hat и Fedora:

01 * * * * root run-parts /etc/cron.hourly
02 4 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly 

    Скрипт run-parts довольно прост: он тупо запускает все исполняемые файлы в заданном каталоге. Есть, как видите, четыре таких каталога, для разных частот запуска. Эта схема упрощает вам жизнь, поскольку надо всего лишь скопировать новый скрипт в соответствующий каталог (в зависимости от того, как часто вы хотите его запускать), и Cron автоматически позаботится о его запуске; но вы теряете гибкость настройки времени выполнения, и все скрипты будут выполняться от имени root. И, конечно, такая схема не способна поддерживать операции вроде «запретить игры утром и разрешить вечером», как в примере ранее.

    По виду /etc/crontab в OpenSUSE 10.2 можно предположить, что его авторы почти полностью забросили системный crontab. Там есть только одна строка, которая выполняет скрипт /usr/lib/cron/run-crons каждые 15 минут. Этот недокументированный и непостижимый среднему уму сценарий, судя по всему, запускает скрипты в каталогах cron. hourly, cron.daily, cron.weekly, cron.monthly, хотя его логика темна.

Cron для простых смертных

    В дополнение к общесистемной таблице /etc/crontab, Vixie Cron позволяет каждому пользователю вести свою таблицу. Они хранятся под именами пользователей в /var/spool/cron/crontab (точное расположение зависит от конкретного дистрибутива).
    Эти файлы имеют тот же формат, что и общесистемная таблица, за одним исключением: там нет поля идентификатора пользователя, так как пользователи запускают эти задачи только сами. Редактировать эти файлы напрямую нельзя; для этого надо запустить crontab -e, которая позволит открыть файл в определенном вами редакторе (вообще-то редактор определяется переменной окружения EDITOR). Зачем нужна оболочка crontab -e? Во-первых, она проверяет синтаксис новых записей, прежде чем их установить, а во-вторых, изменяет метку времени на каталоге spool, сообщая Cron, что один из файлов был изменен. (Что необычно для демона Linux – не надо извещать Cron об изменении файла настроек: он автоматически заметит подмену при пробуждении.)
    Администраторы многопользовательских систем могут контролировать, кому из пользователей разрешено использовать Cron, размещая их имена в одном из двух файлов, /etc/cron.allow и /etc/cron. deny. Пример Может ли Фред запускать Cron? на следующей странице показывает логику принятия решения. Данная возможность, вероятно, была весьма востребована во времена машин с несколькими тысячами учетных записей; но менее актуальна сейчас, когда машины используются одним-двумя пользователями.

Заоблачный проект

    Один из аспектов Cron, который пока игнорировался – окружение, в котором выполняются скрипты. Задания обычного пользователя Cron работают в его домашнем каталоге. Число переменных окружения является минимальным. Cron не считывает скрипт входа пользователя для установки настроек; в частности, в путях поиска находятся только /usr/bin и /bin, поэтому будьте внимательны, запуская программу из crontab – собственно говоря, общепринятой практикой является использование полных путей команд.
    Также принято перенаправлять стандартный вывод и канал ошибок в файл, поэтому вы часто можете видеть в Cron подобные записи:

15 6 * * * /usr/bin/
someprog > /tmp/
someprog.out 2>&1 

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

SHELL=/bin/bash
PATH=/usr/bin:/bin:/usr/local/bin 

    1.    Если вы, как и я, учитесь, экспериментируя, то, возможно, уже решили сами сделать пару записей в crontab, но если кому нужны мои предложения, попробуйте вот что:

FOO=BAR
 PATH=/usr/bin:/bin:/usr/chris/bin
 */5 * * * * env >> env.out
 */10 * * * * echo “hello from a cron job”
 30 * * * * wget http://metoffice.gov.uk/satpics/latest_ir.jpg 

    2.    Проверьте, что ваш crontab правильно установлен, командой crontab -i.
    3.    Займитесь чем-нибудь до конца часа. Может, дочитаете журнал?
    4.     В конце часа проверьте, что в вашем домашнем каталоге появился файл env.out. Он должен содержать множество идентичных копий программного окружения Cron, предваренных отметками времени через пятиминутные интервалы. Вы нашли переменные окружения, которые сами определили в crontab?
    5.    Почитайте свою почту (я имею в виду не почтовый POP-ящик из Evolution, а ваш локальный почтовый файл, который можно прочесть командой mail). Видите сообщения от задачи Cron? Они должны появляться каждые 10 минут.
    6.    Вы получили инфракрасное изображение с метеоспутника? (при необходимости wget автоматически добавит номер к файлу, чтобы избежать его перезаписи, поэтому у вас могут встретиться имена latest_ir.jpg.1, latest_ir.jpg.2 и т.д.). Убедитесь, что Англия покрыта толстым слоем облаков. Если нет – вам, видимо, случайно достался снимок другой страны.
    7.    Если вы не хотите держать этот crontab дальше, удалите его с помощью crontab -r.
Первая запись в crontab в нашем эксперименте просто сохраняет среду, в которой будет выполняться задание. Вторая запись показывает, что если задача создаст вывод, не перенаправленный в файл, то он будет послан пользователю по почте. А третья запись показывает как получать инфракрасное изображение со спутника каждый час. Создание ролика из картинок будет вашим домашним заданием (как принято говорить во всех приличных учебниках).

Часть 2: Эксперимент с Anacron

    Cron превосходен, но имеет слабое место: он спроектирован для машин, которые работают долгое время. Если ваша машина отключена на момент запуска задачи, то задача просто не отработает. Поэтому, если вы планируете на ночь выключать компьютер, то штатные задачи Cron (в 4:02 на Red Hat/Fedora и в 6:25 на Ubuntu) не выполнятся никогда.

Anacron tabl.jpg

    Чтобы справиться с такими ситуациями, был создан новый инструмент Anacron. Согласно лингвистике, «анахроничный» означает «неуместный по хронологии»: например, документальный фильм, демонстрирующий Льва Толстого за ноутбуком, вызовет разве что смешки. Так или иначе, миссия Anacron состоит в обеспечении отработки обязательных ежедневных, еженедельных и ежемесячных задач, при условии, что компьютер будет хотя бы раз в день (или в неделю, или в месяц) включен. Anacron не интересуется точным временем, назначенным для выполнения задания. Файл настройки Anacron, /etc/anacrontab, довольно прост: его синтаксис показан на диаграмме ниже. Вы видите из рисунка, что наименьший период между задачами в Anacron – это день; однако Anacron не является заменой Cron. Вы не можете велеть Anacron запустить команды в определенный час и минуту, поэтому (вспомним мой пример с Cron) нельзя использовать Anacron для отключения доступа в Интернет вечером и восстановления его утром. Чтобы отслеживать, какие программы были запущены и когда, Anacron пишет отметки времени в файлах, помещенных в каталоге /var/spool/anacron, имена которых соответствуют идентификаторам задач в его таблицах. Отметка времени содержит только день, месяц и год, когда была выполнена последняя задача, но не приводит часы, минуты или секунды.

Продвинутый дизайн

    Anacron не является демоном в обычном смысле: демоны запускаются при загрузке системы и подстерегают удобный момент, чтобы что-то проделать, а Anacron при каждом запуске ищет, что надо выполнить, затем выходит. Резонно спросить: и когда же он в самом деле запустится? Пристальный взгляд на файлы настройки Red Hat Enterprise Linux (или Fedora) показывает, что Anacron запускается во время загрузки, через скрипт /etc/init.d/anacron. В этот момент Anacron считывает свою таблицу, проверяет отметки времени файлов в /var/spool/anacron, чтобы узнать, когда каждая задача работала в последний раз, а затем запускает задачи, подлежащие выполнению.
    Для каждой задачи, определенной в таблице anacrontab, выждав определенное время, Anacron запустит команду. Задержки предназначены для того, чтобы Anacron не пытался выполнить все одним махом после загрузки машины, так как пользователь захочет приступить к делу, а не ждать, пока система освободится. Сам по себе Anacron не особо сложен в понимании. Однако все становится куда интереснее, если попытаться выявить связь между Anacron и Cron, особенно если одинаковые задачи выполняются в обеих программах. В настройках Red Hat/Fedora таблица Anacron выглядит так:

1 65 cron.daily run-parts /etc/cron.daily
7 70 cron.weekly run-parts /etc/cron.weekly
30 75 cron.monthly run-parts /etc/cron.monthly 

    Из этой выдержки мы видим, что Anacron просят выполнять в точности те же задачи, что и Cron, то есть в соответствующие интервалы (1, 7 или 30 дней) он использует скрипт run-parts для запуска всех скриптов в /etc/cron.daily, /etc/cron.weekly или /etc/cron.monthly. Вы заметите, что Anacron не запускает скрипты cron.hourly. Как я уже сказал, он для этого не предназначен, потому что записывает отметки времени лишь с точностью до дня.

Сойдите с моей ноги

    Когда одинаковые задачи выполняются и Cron, и Anacron, возникает опасность того, что Cron запустит задачу, которую уже выполнил Anacron, или наоборот. Разные дистрибутивы используют разные трюки для предотвращения этой ситуации. Если внимательно рассмотреть настройку Red Hat\Fedora, то можно обнаружить, что каталог cron.daily содержит скрипт с именем 0anacron, запускающий Anacron с опцией u. Так, мы видим, что Cron запускает Anacron каждый день. Однако опция -u просто говорит Anacron обновить отметки времени, без запуска самих программ. Фактически, Cron сообщает Anacron: «Пожалуйста, учти, что эти команды я уже выполнил сегодня (или на этой неделе, или в этом месяце...), и не трогай их». Ubuntu использует другой прием. Здесь таблица cron выглядит следующим образом:

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
17 * * * * root run-parts /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || run-parts /etc/cron.daily
47 6 * * 7 root test -x /usr/sbin/anacron || run-parts /etc/cron.weekly
52 6 1 * * root test -x /usr/sbin/anacron || run-parts /etc/cron.monthly 

    Часть hourly выглядит понятно; она более-менее похожа на Fedora. Записи на день, неделю и месяц используют трюк с командным интерпретатором, чтобы удостовериться, что run-parts запускается только в отсутствии Anacron. (См. Магический трюк с run-parts во врезке вверху справа.) Обобщая разницу в подходах Red Hat и Ubuntu, можно сказать: «В Red Hat выигрывает Cron. В Ubuntu победа за Anacron.»
    Настройки по умолчанию для Cron и Anacron в различных дистрибутивах могут запутать, однако я бы сказал следующее: вы не обязаны использовать Cron и Anacron именно так, как определил ваш поставщик Linux. Если вы понимаете работу этих двух сервисов и синтаксис файлов настройки, можете заставить их делать то, что хотите вы.


Часть 3: Одноразовые задачи с at

    У нас как раз осталось место, чтобы рассказать о команде at. В отличие от Cron и Anacron, обеспечивающих повторяемые действия, at используется для планирования разовых действий в будущем. Положим, вы захотите, чтобы ваш компьютер пересобрал ядро Linux, пока вы проводите вечер в баре. Вы можете сделать это таким образом:

$ at 20.30
warning: commands will be executed using /bin/sh
at> cd /usr/src/linux at> make all
at> <EOT>
job 2 at Wed Feb 14 19:30:00 2007 

    Как видите, at получает команды, которые вы хотите выполнить, через стандартный ввод до ожидания символа EOT (по умолчанию, ^D). Ваш список поставленных задач можно посмотреть через команду atq.

$ atq 2 Wed Feb 14 19:30:00 2007 a chris $ 

    Демон at (atd) запустит задачу в назначенный момент, экономя вам время на более интересные занятия. Правда, at не доставит вас в бар в назначенное время и не предложит напитков. Однако вы можете из вежливости купить ему пакетик чипсов.
    Подробности об очереди задач хранятся в специальном каталоге (обычно /var/spool/at). Если вы определите задачу или две, а затем посмотрите содержимое этого каталога, то заметите, что в отличие от Cron, at трудится над созданием такой же среды выполнения, как если бы вы только что зашли. Демон atd ответственен за реальное выполнение задач.
    Если вы вдруг передумаете и решите отменить задачу at, можете сделать это командой atrm:

$ atrm 2 
$ 

    Аргументом для atrm является номер задачи (в данном примере это 2).
    Больше всего меня поражает в этой программе изобилие форм записи для задания времени выполнения команды. Верны все следующие варианты:

$ at 14.30 tomorrow
$ at noon Friday
$ at 4pm + 3 days 

    Моим любимцем является ключевое слово teatime как синоним 4 часов дня:

$ at teatime tomorrow 
    Красота! LXF
Персональные инструменты
купить
подписаться
Яндекс.Метрика