Классик навиштааст, ки соатҳои хушбахт тамошо намекунанд. Дар он замонҳои ваҳшӣ на барномасозон буданд ва на Unix, аммо имрӯз барномасозон аниқ медонанд: cron ба ҷои онҳо вақтро ҳисоб мекунад.
Утилитҳои сатри фармон барои ман ҳам заъф ва ҳам кори душвор аст. sed, awk, wc, cut ва дигар барномаҳои кӯҳна бо скриптҳо дар серверҳои мо ҳар рӯз иҷро мешаванд. Бисёре аз онҳо ҳамчун вазифаҳо барои cron тарҳрезӣ шудаанд, як нақшакаш аз солҳои 70-ум.
Муддати тӯлонӣ ман cron-ро рӯякӣ, бидуни ба тафсилот ворид кардан истифода кардам, аммо рӯзе, вақте ки ман ҳангоми иҷро кардани скрипт ба хатогӣ дучор шудам, ман тасмим гирифтам, ки онро ҳамаҷониба тафтиш кунам. Ҳамин тавр ин мақола пайдо шуд ва ҳангоми навиштани он ман бо POSIX crontab, вариантҳои асосии cron дар дистрибюторҳои маъмули Linux ва сохтори баъзеи онҳо шинос шудам.
Иҷрои даврии барномаҳои корбар ё система дар ҳама системаҳои оператсионӣ як зарурати возеҳ аст. Аз ин рӯ, барномасозон зарурати хидматҳоро дарк карданд, ки ба онҳо имкон медиҳанд, ки вазифаҳоро ба таври мутамарказ банақшагирӣ ва иҷро кунанд.
Системаҳои амалиётии ба Unix монанд пайдоиши худро ба Версияи 7 Unix, ки дар солҳои 70-уми асри гузашта дар Bell Labs, аз ҷумла аз ҷониби Кен Томпсони машҳур таҳия шудааст, пайгирӣ мекунанд. Версияи 7 Unix инчунин cron-ро дар бар гирифт, ки хидмат барои мунтазам иҷро кардани вазифаҳои суперкорбарӣ мебошад.
Cron маъмулии муосир як барномаи оддӣ аст, аммо алгоритми амалии версияи аслӣ боз ҳам соддатар буд: хидмат дар як дақиқа як маротиба бедор шуд, ҷадвалро бо супоришҳо аз як файл (/etc/lib/crontab) хонд ва барои он вазифаҳоеро, ки бояд дар айни замон иҷро мешуданд, superuser кунед.
Баъдан, версияҳои такмилёфтаи хидмати оддӣ ва муфид бо ҳама системаҳои амалиётии ба Unix монанд таъмин карда шуданд.
Дар соли 1987, Пол Викси аз корбарони Unix дар бораи хоҳишҳои онҳо дар бораи cron пурсиш карда, версияи дигари демонро нашр кард, ки баъзе мушкилоти cron анъанавиро ислоҳ ва синтаксиси файлҳои ҷадвалро васеъ кард.
Бо версияи сеюми Vixie cron ба талаботи POSIX ҷавобгӯ буд, илова бар ин, барнома дорои литсензияи либералӣ буд, ё дурусттараш, умуман иҷозатнома вуҷуд надошт, ба истиснои хоҳишҳо дар README: муаллиф кафолат намедиҳад, номи муаллиф нест кардан мумкин нест ва барномаро танҳо дар якҷоягӣ бо рамзи сарчашма фурӯхтан мумкин аст. Ин талаботҳо бо принсипҳои нармафзори озод, ки дар он солҳо маъруфият пайдо мекарданд, мувофиқ буданд, аз ин рӯ баъзе дистрибюсияҳои асосии Linux, ки дар аввали солҳои 90-ум пайдо шуданд, Vixie cron-ро ҳамчун системаи худ гирифтанд ва ҳоло ҳам онро таҳия мекунанд.
Махсусан, Red Hat ва SUSE як штангаи Vixie cron - cronie-ро таҳия мекунанд ва Debian ва Ubuntu нашри аслии Vixie cronро бо часпакҳои зиёд истифода мебаранд.
Биёед аввал бо утилитаи корбар crontab, ки дар POSIX тавсиф шудааст, шинос шавем, баъд аз он мо васеъшавии синтаксиси дар Vixie cron пешниҳодшуда ва истифодаи вариантҳои Vixie cron дар дистрибюторҳои маъмули Linuxро дида мебароем. Ва ниҳоят, гелос дар торт таҳлили дастгоҳи демони крон мебошад.
Crontab POSIX
Агар cron аслӣ ҳамеша барои суперкорбар кор мекард, банақшагириҳои муосир аксар вақт бо вазифаҳои корбарони оддӣ сарукор доранд, ки бехатартар ва қулайтар аст.
Кронҳо ҳамчун маҷмӯи ду барнома таъмин карда мешаванд: демони доимии cron ва утилитаи crontab, ки барои корбарон дастрас аст. Охирин ба шумо имкон медиҳад, ки ҷадвалҳои вазифаҳои мушаххаси ҳар як корбари системаро таҳрир кунед, дар ҳоле ки демон супоришҳоро аз ҷадвалҳои корбар ва система оғоз мекунад.
В Стандарти POSIX рафтори демон ба ҳеҷ ваҷҳ тасвир карда намешавад ва танҳо барномаи корбар ба расмият дароварда мешавад crontab. Мавҷудияти механизмҳои оғоз кардани вазифаҳои корбар, албатта, дар назар аст, аммо ба таври муфассал тавсиф карда нашудааст.
# строки-комментарии игнорируются
#
# задача, выполняемая ежеминутно
* * * * * /path/to/exec -a -b -c
# задача, выполняемая на 10-й минуте каждого часа
10 * * * * /path/to/exec -a -b -c
# задача, выполняемая на 10-й минуте второго часа каждого дня и использующая перенаправление стандартного потока вывода
10 2 * * * /path/to/exec -a -b -c > /tmp/cron-job-output.log
# Запускается после перезагрузки системы
@reboot /exec/on/reboot
# Запускается раз в день
@daily /exec/daily
# Запускается раз в час
@hourly /exec/daily
Сипас, раванд "демонизатсия" мешавад: он нусхаи кӯдаки равандро тавассути занги fork ва сессияи нав дар раванди кӯдак (занг setsid) эҷод мекунад. Раванди волидайн дигар лозим нест ва он хориҷ мешавад:
switch (fork()) {
case -1:
/* критическая ошибка и завершение работы */
exit(0);
break;
case 0:
/* дочерний процесс */
(void) setsid();
break;
default:
/* родительский процесс завершает работу */
_exit(0);
}
Қатъи раванди волидайн қулфро дар файли қулф мебарорад. Илова бар ин, зарур аст, ки PID дар файл ба кӯдак навсозӣ карда шавад. Пас аз ин, базаи вазифаҳо пур карда мешавад:
/* первичная загрузка задач */
load_database(&database);
/* запустить задачи, поставленные к выполнению после перезагрузки системы */
run_reboot_jobs(&database);
/* сделать TargetTime началом ближайшей минуты */
cron_sync();
while (TRUE) {
/* выполнить задачи, после чего спать до TargetTime с поправкой на время, потраченное на задачи */
cron_sleep();
/* перечитать конфигурацию */
load_database(&database);
/* собрать задачи для данной минуты */
cron_tick(&database);
/* перевести TargetTime на начало следующей минуты */
TargetTime += 60;
}
Функсияи cron_sleep бевосита дар иҷрои вазифаҳо иштирок мекунад, вазифаҳои job_runqueue (шумурда ва иҷро кардани вазифаҳо) ва do_command (иҷро кардани ҳар як вазифаи инфиродӣ) даъват мекунад. Функсияи охирин бояд ба таври муфассал баррасӣ карда шавад.
switch (fork()) {
case -1:
/*не смогли выполнить fork */
break;
case 0:
/* дочерний процесс: на всякий случай еще раз пробуем захватить главный лок */
acquire_daemonlock(1);
/* переходим к формированию процесса задачи */
child_process(e, u);
/* по завершению дочерний процесс заканчивает работу */
_exit(OK_EXIT);
break;
default:
/* родительский процесс продолжает работу */
break;
}
Дар child_process мантиқи зиёде мавҷуд аст: он баромади стандартӣ ва ҷараёнҳои хатогиро қабул мекунад, сипас онҳоро ба почта мефиристад (агар тағирёбандаи муҳити MAILTO дар ҷадвали вазифаҳо нишон дода шуда бошад) ва ниҳоят, мунтазири раванди асосии вазифа аст пурра.
Раванди вазифа аз ҷониби як штангаи дигар ташаккул меёбад:
switch (vfork()) {
case -1:
/* при ошибки сразу завершается работа */
exit(ERROR_EXIT);
case 0:
/* процесс-внук формирует новую сессию, терминал и т.д.
*/
(void) setsid();
/*
* дальше многословная настройка вывода процесса, опустим для краткости
*/
/* смена директории, пользователя и группы пользователя,
* то есть процесс больше не суперпользовательский
*/
setgid(e->gid);
setuid(e->uid);
chdir(env_get("HOME", e->envp));
/* запуск самой команды
*/
{
/* переменная окружения SHELL указывает на интерпретатор для запуска */
char *shell = env_get("SHELL", e->envp);
/* процесс запускается без передачи окружения родительского процесса,
* то есть именно так, как описано в таблице задач пользователя */
execle(shell, shell, "-c", e->cmd, (char *)0, e->envp);
/* ошибка — и процесс на запустился? завершение работы */
perror("execl");
_exit(ERROR_EXIT);
}
break;
default:
/* сам процесс продолжает работу: ждет завершения работы и вывода */
break;
}
Ин асосан ҳама cron аст. Ман баъзе тафсилоти ҷолибро сарфи назар кардам, масалан, баҳисобгирии корбарони дурдаст, аммо ман чизи асосиро нишон додам.
Пас аз он
Cron як барномаи ҳайратовар содда ва муфид аст, ки дар беҳтарин анъанаҳои ҷаҳони Unix сохта шудааст. Вай ҳеҷ чизи иловагӣ намекунад, аммо вай дар тӯли якчанд даҳсолаҳо кори худро олиҷаноб иҷро мекунад. Гирифтани коди версияи бо Ubuntu мавҷудбуда на бештар аз як соат вақтро гирифт ва ман хеле шавқовар будам! Умедворам, ки ман тавонистам онро бо шумо мубодила кунам.
Ман дар бораи шумо намедонам, аммо каме ғамгинам, ки дарк мекунам, ки барномасозии муосир бо тамоюли аз ҳад зиёд печида ва абстрактӣ, муддати тӯлонӣ барои чунин соддагӣ мусоид набуд.