ЗАНЯТИЕ 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.
-l — вывести содержимое файла crontab для пользователя на экран;
-r — удаление текущего файла crontab;
-u user — где user это пользователь от имени которого будет производиться запуск crontab (таким образом root может редактировать задания пользователей)
Все команды, которые запускает крон можна посмотреть в логах в /var/log/cron, а также файлах cron1, cron2 и т.д. (в них находятся более старые данные).
# 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 позволяют определять время запуска команды или последовательности команд. При помощи команды 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> - вновь запускает приостановленное задание в фоновом режиме.
Все процессы, за исключением at и batch, завершаются, когда пользователь выходит из системы. Если необходимо, чтобы после выхода пользователя из системы процесс в фоновом режиме продолжал выполняться, то необходимо использовать команду nohup. Команда nohup имеет следующий формат:
nohup command &<CR>
Предположим, надо, чтобы команда grep осуществила поиск во всех файлах в текущем справочнике строки "word" и перенаправила вывод в файл word.list, и затем, не ожидая завершения, имеется желание выйти из системы, то надо ввести следующую строку:
nohup grep word * > word.list & <CR>
Завершить команду nohup можно с помощью команды kill.