<< Предыдущий раздел | /\ Содержание | >> Следующий раздел

Что такое временное исполнение

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

Есть два варианта временного исполнения: однократное исполнение команд в указанный день в указанное время (команда at) и периодическое исполнение одних и тех же команд -- например, раз в сутки (команда crontab).

В обоих случаях можно запускать только неинтерактивные команды -- т.е. такие, которые не взаимодействуют с терминалом, т.к. команды запускаются "сами по себе", без терминала. Хотя, в принципе, можно запускать таким образом X-программы, делать это следует с осторожностью.

Результат исполнения команд (т.е. то, что они в обычной ситуации выдали бы на экран) будет послан по e-mail. Если выдача пустая, то письмо не посылается.

Исполнение скрипта в указанное время -- at

Команда at позволяет указать системе, что некую последовательность команд (реально -- скрипт на языке shell) надо исполнить в указанное время. Этот набор команд называется заданием. ("At" в переводе означает "в", т.е. "исполнить В такое-то время".)

Формат вызова at следующий:

at [-f файл-содержащий-команды] <время>

Если есть ключ "-f", то at считает скрипт из указанного файла, если нет -- то со стандартного ввода (обычно с клавиатуры, завершить ввод при этом надо комбинацией <Ctrl+D>).

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

Ниже приведено несколько примеров указания времени. При этом предполагается что они указываются в субботу, 15 мая 1999 года в 18:10.

Несколько примеров указания времени команде at
УказаниеСмысл
19:00Сегодня в 7 часов вечера 0 минут
17:30Завтра в 5 часов 30 минут после полудня
now + 53 minutesЧерез 53 минуты (т.е. в 19:03)
now + 1 dayЗавтра в это же время
13:20 tomorrowЗавтра в 13:20
10:00 today + 5 daysВ 10 часов утра через пять дней (т.е. 20 мая)
14:30 Feb 15,2001В 14:30 15 февраля 2001 года

День указывается после времени. Если день не указан, то подразумевается текущий день или, если это время уже прошло (как во втором примере), следующий. Аналогично, если указанные месяц/день уже прошли, то считается, что они относятся к следующему году.

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

Если указывается уже прошедшее время, то разные системы ведут себя по разному -- к примеру, в ответ на "03:00 saturday" Linux выполнит скрипт немедленно, а Irix скажет "too late".

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

/usr/doc/at-3.1.7/timespec

Пример использования at:

bobby:~% whoami
ivanov
bobby:~% at 23:00 today
at> who
at> <EOT>
warning: commands will be executed using /bin/sh
job 12 at 1999-05-15 23:00
bobby:~% _

В этом примере в 11 часов вечера текущего дня будет выполнена команда who (показывающая список пользователей), а результат ее исполнения будет отправлен пользователю "ivanov@bobby".

При чтении списка команд не из файла (т.е. без ключа "-f"), at предваряет каждую вводимую строку приглашением "at>". Символы "<EOT>" показывают то место, где мы нажали <Ctrl+D>.

В конце at печатает напоминание, что скрипт будет выполняться при помощи интерпретатора /bin/sh, а также идентификатор задания и время исполнения в виде "год-месяц-день часы:минуты".

Идентификатор задания служит для дальнейших ссылок на него -- он показывается в листинге заданий и должен указываться при необходимости удалить задание. В разных системах идентификаторы заданий имеют разный формат -- в Linux это просто последовательно увеличивающееся число, а в других системах оно может, к примеру, иметь вид "926798400.a" или "947883600.a+500".

Для просмотра списка заданий служит команда atq:

viper:~% atq
12      1999-05-15 23:00 a
viper:~% _

Она отображает номер задания, время исполнения и номер очереди, в которой оно находится. По умолчанию все задания помещаются в очередь "a". У исполняющихся в данный момент заданий вместо очереди отображается символ "=":

bobby:~% at now
at> sleep 120
at> w
at> <EOT>
warning: commands will be executed using /bin/sh
job 14 at 1999-05-15 19:05
bobby:~% atq
12      1999-05-15 23:00 a
14      1999-05-15 19:05 =
bobby:~% _

(Команда sleep "спит" (т.е. ничего не делает) в течение указанного количества секунд.)

Удалить задание из очереди можно командой atrm, ей указывается идентификатор задания:

bobby:~% atq
12      1999-05-15 23:00 a
bobby:~% atrm 12
bobby:~% atq
bobby:~% _

При попытке удалить уже исполняющееся задание выдается сообщение "Warning: deleting running job", и хотя задание из очереди удаляется, оно продолжает исполняться.

Просмотреть содержимое задания можно командой "at -c". Ее выдача довольно показательна: в начало скрипта добавляется настройка переменных окружения (т.е. всем переменным окружения, существующим на момент запуска at, присваиваются такие же значения).

Замечание
В системах клона SystemV (таких, как Solaris и IRIX) вместо команды atrm используется "at -r", а вместо atq -- "at -l". Команда "at -c" в них не поддерживается.

Периодическое исполнение команд -- crontab

Для периодического исполнения команд служит подсистема Cron, а команда для редактирования списка команд используется команда crontab. (Слово "cron" -- это сокращение от "chronograph".)

У каждого пользователя для управления периодическим исполнением своих команд есть собственный так называемый crontab-файл ("crontab" -- "CRON driving TABle" -- "таблица управления Cron'ом). Этот (изначально пустой) файл расположен в недоступной для самого пользователя директории, и может просматриваться и редактироваться только при помощи команды crontab.

У команды crontab есть четыре варианта вызова:

КомандаДействие
crontab ФАЙЛСкопировать ФАЙЛ в crontab-файл
crontab -lВыдать содержимое crontab-файла
crontab -rУдалить crontab-файл
crontab -eРедактировать crontab-файл

Для редактирования по умолчанию вызывается vi (причем в RedHat 5.2 crontab его не находит и "обламывается"). Чтобы использовать другой текстовый редактор (например, joe), надо указать его в переменной окружения EDITOR:

bobby:~% export EDITOR=joe
bobby:~% crontab -e

В каждой строке crontab-файла указывается команда и периодичность ее запуска. Пустые строки и строки, начинающиеся с символа "#", игнорируются.

Каждая строка состоит из шести полей, разделенных пробелами или символами табуляции. Формат строки следующий:

Минута Час ДеньМесяца Месяц ДеньНедели Команда

Например, строка

0 23 * * 0 /usr/bin/who
будет каждый понедельник в 23:00 запускать команду who и отсылать по e-mail выдаваемый ею список пользователей.

Команды могут быть любыми, а не только скриптами. Вообще говоря, могут указываться любые сложные команды, допустимые в языке shell, в том числе содержащие перенаправление ввода/вывода. Но команды следует указывать с полным путем -- т.е. /home/users/ivanov/bin/mystatcmd, а не просто "mystatcmd". (Другой вариант -- присвоить в начале crontab-файла значение переменной окружения PATH, но мы это рассматривать не будем.)

Замечание
Узнать полный путь программы можно при помощи команды which. Например, команда "which finger" выдаст "/usr/bin/finger".

Месяцы нумеруются с 1 по 12, дни недели -- с 0 по 6 (0 -- воскресенье, 1 -- понедельник, 6 -- суббота). В Linux месяцы и дни недели можно указывать трехсимвольными именами (т.е. Jan, Feb, Mar...; Sun, Mon, Tue...).

Cron исполняет команду тогда, когда значения всех полей Минута, Час, Месяц и ДеньНедели или ДеньМесяца совпадают с текущим временем. Символ "*" означает "любое" или "каждое". Можно указывать несколько значений через запятую, например "10,30,50" в поле Минута означает "в 10, 30 и 50 минут". Допускаются также диапазоны через дефис, например, "1-5" в поле ДеньНедели означает "с понедельника по пятницу".

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

30 4 1,15 * 5 /usr/bin/vmstat
будет запускать vmstat в 4:30 утра по первым и пятнадцатым числам каждого месяца, плюс каждую пятницу.

Несколько примеров:

# Запускать df каждый день в 7:00 утра 
0 7 * * * /bin/df

# Заказывать кофе каждый рабочий день в 10:00, 13:00 и 17:00
0 10,13,17 * * 1-5 echo Now| mail -s "Coffee, please" waitor@restaurant

# Производить подсчет своего бюджета 6 и 21 числа каждого месяца
0 14 6,21 * * /home/users/ivanov/bin/calcbudget

Очень хорошая и полная документация на crontab-файлы есть в man-странице crontab(5) (т.е. для просмотра надо набрать "man 5 crontab").

Замечание
В старых BSD-системах пользоваться подсистемой Cron может только "root" (если только стандартный пакет Cron не заменен на Vixie-Cron, что, впрочем, в последнее время стало почти правилом).


<< 
Предыдущий раздел | /\ Содержание | >> Следующий раздел