ЗАНЯТИЕ 11-1: расписание заданий

Ключевые слова: cron, crontab, at, batch, nuhup

Выполнение процессов в заданное время по расписанию

Cron — это программа, которая используется в unix-системах для выполнения заданий в определенное время. Задания могут запускаться как единоразово, так и переодически.

Служба пранирования заданий состоит из демона, который обычно называется crond и набора конфигурационных файлов – для каждого из пользователей в /var/spool/cron, общесистемного /etc/crontab и /etc/cron.d.

При загрузке системы, запускается демон cron и проверяет очередь заданий at и заданий пользователей в файлах crontab. При запуске, демон cron сначала проверяет каталог /var/spool/cron на наличие файлов crontab, которые имеют имена пользователей, соответствующие именам пользователей из /etc/passwd, также он проверяет /etc/crontab и наличие файлов в директории /etc/cron.d/. Найденные файлы загружаются в память, далее крон проверяет ежеминутно нужно ли запускать какое либо из заданий в данную минуту, кроме этого проверяется происходило ли обновления директории spool, cron.d или файла /etc/crontab.В случае обновлений, измененные файлы заново перечитываются. Таким образом, при обновлении файла крона нет необходимости производить его перезагрузку, все файлы будут считаны автоматически при последующей проверке.

Стандартный файл /etc/crontab выглядит так:

 

SHELL=/bin/bash

PATH=/sbin:/bin:/usr/sbin:/usr/bin

MAILTO=root

HOME=/

 

# run-parts

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

 

Первые четыре строки — это переменные, настраивающие среду окружения, в котором будут работать задачи cron. Значение переменной SHELL сообщает системе о том, какую оболочку использовать (в этом примере будет использована оболочка bash, если переменная не указана, то значение будет взято из /etc/passwd для пользователя являющимся владельцем файла), а переменная PATH определяет пути, используемые для выполнения команд. Результат выполнения задач cron будет выслан по электронной почте пользователю, определённому в переменной MAILTO. Если в качестве значения переменной MAILTO задана пустая строка (MAILTO=””), электронные письма отправляться не будут. Переменная HOME задаёт домашний каталог, используемый при выполнения команд или сценариев.

Каждая строка в файле /etc/crontab имеет следующий формат:

minute hour day month dayofweek command
minute — любое целое число от 0 до 59
hour — любое целое от 0 до 23
day — любое целое от 1 до 31 (день должен быть корректным, если указан месяц)
month — любое целое от 1 до 12 (или короткое название месяца, например: jan, feb и так далее)
dayofweek — любое целое от 0 до 7, где 0 или 7 означает Воскресенье (или короткое название дня недели, например: sun, mon и так далее)
command — команда, которая должны быть выполнена.

 

Командой может быть как простая команда, например, ls /proc >> /tmp/proc, или команда запуска написанного вами специального сценария.

Для любых указанных выше параметров можно использовать звездочку (*), что означает все допустимые значения. Например, если поставить звёздочку в значении месяца, команда будет выполняться каждый месяц во время, указанное другими параметрами.
Дефис (-) между целыми числами обозначает диапазон чисел. Например, 1-4 означает целые числа 1, 2, 3 и 4.
Список значений, разделенных запятыми (,), обозначает перечень. Например, перечисление 3, 4, 6, 8 означает четыре указанных целых числа.
Косая черта (/) используется для определения шага значений. Целочисленное значение может быть пропущено в диапазоне, если после диапазона указать /<целое>. Например, значение минут 0-59/2, определяет, что будет пропущена каждая вторая минута. В качестве шага значений также может быть указана звёздочка. Например, значение месяца */3 определяет, что будет пропущен каждый третий месяц.

Таким образом в файле /etc/crontab определен запуск сценариев из директорий /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly и /etc/cron.monthly соответственно ежечасно, ежедневно, еженедельно и ежемесячно. Содержимое из этих каталогов будет запускаться с правами доступа пользователя root и файлы должны иметь права доступа на «выполнение».

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

Другие пользователи также могут настраивать свои задачи cron с помощью программы crontab. Для этого необходимо запустить команду crontab -e (будет вызван текстовый редактор, указанный в значении переменной окружения VISUAL или EDITOR) и отредактирвоать файл (формат тот же что и у /etc/crontab). После сохранения изменений файл будет записан в соответствии с именем пользователя в директории /var/spool/cron/username.

Другие полезные опции команды crontab:

-l — вывести содержимое файла crontab для пользователя на экран;
-r — удаление текущего файла crontab;
-u user — где user это пользователь от имени которого будет производиться запуск crontab (таким образом root может редактировать задания пользователей)

Все команды, которые запускает крон можна посмотреть в логах в /var/log/cron, а также файлах cron1, cron2 и т.д. (в них находятся более старые данные).

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

# crontab -l

# каждые 5мин синхронизироваться с сервером времени и не отправлять

#уведомление об этом, т.е. stdout и stderr направить в /dev/null

*/5  *  *  *  *   root  /usr/sbin/ntpdate time.ukr.net > /dev/null 2>&1

# на 1-ой и 31-ой минуте с 0 до 5 запусать скрипт в ~/script.py

1,31    0-5   *   *   *  /home/user/script.py

# каждый рабочий день в 13:00

0 13 * * 1-5 /home/user/script.py

# выполнять 1 числа каждого месяца в 15 часов

0 15 1 * * /home/user/script.py

# Каждые два часа в 25 минут (тоесть в 0:25, 2:25, 4:25 и т.д.)

#запускать команду top и дописывать ее вывод в файл

25 */2 * * * /usr/bin/top -b -n 1 >> /home/user/top_stats.txt

 

Выполнение, останов и повторный запуск процессов

В этом подразделе описывается:

Запуск команд в заданное время

Команды batch и at позволяют определять время запуска команды или последовательности команд. При помощи команды batch система определяет время запуска команды, это можно определить с помощью команды at. Обе команды ожидают ввод со стандартного ввода (терминала); список команд, вводимых с терминала, должен завершаться нажатием клавиши ^d (одновременное нажатие клавиши Ctrl и клавиши d).

Команда batch очень полезна, если необходимо запустить процесс или программу, которые занимают много системного времени. Команда batch представляет системе задание (содержащее последовательность команд для выполнения). Задание ставится в очередь и запускается как только у системы появляется возможность. Это позволяет системе быстро отвечать на запросы других пользователей. Общий формат команды batch:

 

        batch<CR>

        первая команда<CR>

        .

        .

        .

        последняя команда<CR>

        <^d>

 

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

 

        batch command_line<CR>

 

В следующем примере batch используется для выполнения команды grep в согласованное время. Команда grep осуществляет поиск всех файлов в текущем справочнике и перенаправляет вывод в файл dol.file:

 

        $ batch<CR>

        grep dollar * > dol.file<CR>

        <^d>

        job 155223141.b at Sun Dec 11:14:54 1989

        $

 

После того как определено задание batch, система выдаст ответ, в котором даны номер задания, дата и время. Номер задания не то же самое, что номер процесса, который система генерирует, когда запускается команда в фоновом режиме.

Команда at позволяет вам указывать точное время выполнения команд. Общий фомат команды at:

 

        at time<CR>

        первая команда<CR>

        .

        .

        .

        последняя команда<CR>

        <^d>

 

Аргумент time состоит из времени дня и даты, если дата не сегодняшняя.

В следующем примере показано, как использовать команду at для посылки сообщения happy birthday пользователю с регистрационным именем emily:

 

        $ at 8:15am Feb 27<CR>

        banner happy birthday | mail emily<CR>

        <^d>

        $

 

Надо обратите внимание на то, что команда at подобно команде batch выдает ответ с номером задания, датой и временем.

Если больше нет необходимости, чтобы команды, находящиеся в данный момент в очереди заданий batch или at были выполнены, то можно удалить их из очереди. Для этого надо воспользоваться опцией -r в команде at, указав ее с номером задания. Общий формат такой команды:

 

        at -r jobnumber<CR>

 

Например, чтобы удалить предыдущее задание at, надо ввести:

 

        at -r 453400603.a<CR>

 

Если номер задания неизвестен, то команда :

 

        at -l

 

распечатает список текущих заданий в очереди batch или at, как показано на следующем экране:

 

        $ at -l<CR>CW

        user mylogin 168302040.a at Sat Nov 25 13:00:00 1989

        user mylogin 453400603.a at Fri Feb 24 08:15:00 1989

        $

 

Таким образом команда at выполняет команды в указанное время. Можно использовать от одной до 4-х цифр и буквосочетания "am" и "pm", чтобы указать время. Чтобы указать дату, можно задать имя месяца и вслед за ним число. Если задание должно быть выполнено сегодня, то дату вводить не надо.

Пример:

 

        at 08:15am Feb 27

        at 5:14pm Sept 24

Получить состояние запущенного процесса

Команда ps выдает состояние всех процессов, запущенных на данный момент. Например,  можно использовать команду ps, чтобы просмотреть состояние всех процессов, которые запущены в фоновом режиме, применив символ &.

В следующем подпункте обсуждается вопрос, как применить номер PID (идентификатор процесса), чтобы остановить выполнение команды. PID является уникальным номером, который система UNIX назначает каждому активному процессу.

В следующем примере команда grep запускается в фоновом режиме и затем выдается команда ps. Система сообщает в ответ номер идентификации процесса (PID) и номер терминала (TTY). Она также выдает время выполнения каждого процесса (TIME) и имя команды, которая выполняется (COMMAND):

 

        $ grep word * > temp <CR>

        28223

        $

        $ ps<CR>

        PID         TTY       TIME       COMD

        28124       tty10     0:00       sh

        28223       tty10     0:04       grep

        28224       tty10     0:04       ps

        $

 

Надо обратить внимание на то, что система распечатала номер PID для команды grep так же, как и для всех других запущенных процессов: для самой команды ps и команды sh, которая была запущена во время регистрации пользователя.

Можно также приостановить и вновь запустить программу, если в системе предусмотрена функция управления заданиями. Команда jobs выдает список текущих фоновых процессов, запущенных или приостановленных. Команда jobs дополнительно к PID распечатывает идентификатор задания (JID) и имя задания. Чтобы вновь запустить приостановленное задание, либо возобновить фоновый процесс в оперативном режиме, необходимо знать JID. JID распечатывается на экране каждый раз, когда вводится команда запуска или останова процесса. Если ввести:

 

        jobs<CR>

 

то на экране появится следующая информация:

 

        [JID] - Stopped (signal) <имя задания>

 

или

 

        [JID] + Running      <имя задания>

Завершение активных процессов

Команда kill завершает активные процессы в фоновом режиме и команда stop приостанавливает временно процессы. Общий формат этих команд:

 

        kill PID<CR>

 

или

 

        stop JID<CR>

 

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

Пример:

 

        $ kill 28223<CR>

        28223 Terminated

        $

 

После того как система выдаст ответ на запрос, на экране появится подсказка $, означающая, что процесс завершен. Если система не найдет указанный PID, то появится сообщение об ошибке:

 

        kill:28223:No such process

 

Чтобы приостановить оперативный процесс (если активна функция управления заданиями), надо ввести:

 

        ctrl Z

 

На экране появится следующее сообщение:

 

        <JID> Stopped(user)  <имя задания>

Запуск остановленного задания

Если функция управления заданиями активна, то можно вновь запустить приостановленный процесс. Чтобы вновь запустить процесс, остановленный командой stop, надо сначала определить JID с помощью команды jobs, затем можно использовать JID со следующими командами:

 

fg <JID> - возобновляет приостановленное задание или переводит задание из фонового режима в оперативный;

 

bg <JID> - вновь запускает приостановленное задание в фоновом режиме.

Использование команды nohup

Все процессы, за исключением at и batch, завершаются, когда пользователь выходит из системы. Если необходимо, чтобы после выхода пользователя из системы процесс в фоновом режиме продолжал выполняться, то необходимо использовать команду nohup. Команда nohup имеет следующий формат:

        nohup command &<CR>

 

Предположим, надо, чтобы команда grep осуществила поиск во всех файлах в текущем справочнике строки "word" и перенаправила вывод в файл word.list, и затем, не ожидая завершения, имеется желание выйти из системы, то надо ввести следующую строку:

 

        nohup grep word * > word.list & <CR>

 

Завершить команду nohup можно с помощью команды kill.