Linux ичинде Cron: тарыхы, колдонуу жана түзмөк

Linux ичинде Cron: тарыхы, колдонуу жана түзмөк

Классик бактылуу сааттар көрбөйт деп жазган. Ошол жапайы мезгилде программисттер да, Unix да болгон эмес, бирок бүгүнкү күндө программисттер так билишет: cron алардын ордуна убакытты көзөмөлдөйт.

Буйрук сабынын утилиталары мен үчүн алсыздык жана түйшүк. sed, awk, wc, cut жана башка эски программалар биздин серверлерибизде күн сайын скрипттер аркылуу иштетилет. Алардын көбү 70-жылдардагы пландоочу cron үчүн тапшырмалар катары иштелип чыккан.

Узак убакыт бою cronду үстүртөн, майда-чүйдөсүнө чейин колдончумун, бирок бир күнү сценарийди иштетип жатканда катага туш болгондо, аны кылдаттык менен карап чыгууну чечтим. Бул макала ушундайча пайда болду, аны жазып жатып мен POSIX crontab, популярдуу Linux дистрибуцияларындагы негизги cron варианттары жана алардын айрымдарынын структурасы менен тааныштым.

Сиз Linux колдонуп жатасызбы жана cron тапшырмаларын аткарып жатасызбы? Сиз Unixте тутумдук колдонмолордун архитектурасына кызыгасызбы? Анда биз жолго чыгабыз!

ыраазы

Түрлөрдүн келип чыгышы

Колдонуучунун же тутумдук программалардын мезгил-мезгили менен аткарылышы бардык операциялык системаларда ачык зарылчылык болуп саналат. Ошондуктан, программисттер борборлоштурулган пландоо жана тапшырмаларды аткарууга мүмкүндүк берген кызматтардын зарылдыгын көп убакыт мурун түшүнүшкөн.

Unixке окшош операциялык системалар өткөн кылымдын 7-жылдарында Bell Labs лабораториясында, анын ичинде атактуу Кен Томпсон тарабынан иштелип чыккан Unix 70-версиясынан келип чыккан. Версия 7 Unix ошондой эле cron, супер колдонуучу тапшырмаларын үзгүлтүксүз аткаруу үчүн кызматты камтыйт.

Кадимки заманбап cron – бул жөнөкөй программа, бирок оригиналдуу версиянын иштөө алгоритми андан да жөнөкөй: кызмат мүнөтүнө бир жолу ойгонуп, бир файлдан (/etc/lib/crontab) тапшырмалары бар таблицаны окуп, азыркы учурда аткарылышы керек болгон тапшырмаларды супер колдонуучу.

Кийинчерээк, жөнөкөй жана пайдалуу кызматтын жакшыртылган версиялары бардык Unix сыяктуу операциялык системалар менен камсыз болгон.

crontab форматынын жалпыланган сыпаттамасы жана утилитанын ишинин негизги принциптери 1992-жылы Unix сыяктуу операциялык системалардын негизги стандартына - POSIX-ке киргизилген, ошентип, де-факто стандартынан cron де-юре стандартка айланган.

1987-жылы Пол Викси Unix колдонуучуларынын кронго болгон каалоолору боюнча сурамжылоо жүргүзүп, салттуу cronдун айрым көйгөйлөрүн оңдогон жана таблица файлдарынын синтаксисин кеңейткен демондун дагы бир версиясын чыгарды.

Vixie cron үчүнчү версиясында POSIX талаптарына жооп бере баштады, андан тышкары, программанын либералдык лицензиясы бар болчу, тагыраак айтканда, READMEдеги каалоолордон башка эч кандай лицензия жок болчу: автор кепилдик бербейт, автордун аты-жөнү жок кылынышы мүмкүн эмес жана программаны баштапкы код менен гана сатууга болот. Бул талаптар ошол жылдары популярдуулукка ээ болгон эркин программалык камсыздоонун принциптерине шайкеш болуп чыкты, ошондуктан 90-жылдардын башында пайда болгон негизги Linux дистрибьюторлорунун айрымдары Vixie cronду система катары кабыл алышкан жана аны бүгүнкү күндө да иштеп чыгууда.

Атап айтканда, Red Hat жана SUSE Vixie cron - cronie айрысын иштеп чыгышат, ал эми Debian жана Ubuntu көптөгөн тактары бар Vixie cronдун түп нускасын колдонушат.

Келгиле, адегенде POSIXте сүрөттөлгөн crontab колдонуучу утилитасы менен таанышалы, андан кийин биз Vixie cronдо берилген синтаксис кеңейтүүлөрүн жана популярдуу Linux дистрибуцияларында Vixie cron вариацияларын колдонууну карайбыз. Акыр-аягы, торттогу алча - крон демон аппаратынын анализи.

POSIX crontab

Эгерде баштапкы cron дайыма супер колдонуучу үчүн иштесе, заманбап пландоочулар көбүнчө жөнөкөй колдонуучулардын тапшырмалары менен иштешет, бул коопсуз жана ыңгайлуу.

Крондор эки программанын жыйындысы катары берилет: тынымсыз иштеп жаткан cron демону жана колдонуучуларга жеткиликтүү crontab утилитасы. Акыркысы системадагы ар бир колдонуучуга мүнөздүү тапшырма таблицаларын оңдоого мүмкүндүк берет, ал эми демон колдонуучунун жана системанын таблицаларынан тапшырмаларды ишке киргизет.

В POSIX стандарты демондун жүрүм-туруму эч кандай сүрөттөлбөйт жана колдонуучунун программасы гана формалдаштырылган crontab. Колдонуучунун тапшырмаларын ишке киргизүү үчүн механизмдердин бар экендиги, албетте, болжолдонгон, бирок майда-чүйдөсүнө чейин сүрөттөлгөн эмес.

crontab утилитасын чакыруу менен сиз төрт нерсени аткара аласыз: колдонуучунун тапшырмалар таблицасын редактордо түзөтүү, таблицаны файлдан жүктөө, учурдагы тапшырмалар таблицасын көрсөтүү жана тапшырмалар таблицасын тазалоо. crontab утилитасынын ишинин мисалдары:

crontab -e # редактировать таблицу задач
crontab -l # показать таблицу задач
crontab -r # удалить таблицу задач
crontab path/to/file.crontab # загрузить таблицу задач из файла

Чакырганда crontab -e стандарттык чөйрө өзгөрмөсүндө көрсөтүлгөн редактор колдонулат EDITOR.

Милдеттердин өзү төмөнкү форматта сүрөттөлөт:

# строки-комментарии игнорируются
#
# задача, выполняемая ежеминутно
* * * * * /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

Жазуулардын алгачкы беш талаалары: мүнөттөр [1..60], сааттар [0..23], айдын күндөрү [1..31], айлар [1..12], жуманын күндөрү [0. .6], мында 0 жекшемби. Акыркы, алтынчы талаа стандарттык буйрук интерпретатору тарабынан аткарыла турган сап.

Биринчи беш талаада баалуулуктарды үтүр менен бөлүп көрсөтүүгө болот:

# задача, выполняемая в первую и десятую минуты каждого часа
1,10 * * * * /path/to/exec -a -b -c

Же дефис менен:

# задача, выполняемая в каждую из первых десяти минут каждого часа
0-9 * * * * /path/to/exec -a -b -c

Колдонуучунун тапшырмаларды пландаштырууга кирүү мүмкүнчүлүгү POSIXте cron.allow жана cron.deny файлдары менен жөнгө салынат, алар тиешелүүлүгүнө жараша crontabга кирүү мүмкүнчүлүгү бар колдонуучуларды жана программага кирүү мүмкүнчүлүгү жок колдонуучуларды тизмелейт. Стандарт бул файлдардын жайгашкан жерин эч кандай жол менен жөнгө салбайт.

Стандартка ылайык, ишке киргизилген программаларга жок дегенде төрт чөйрө өзгөрмөлөрү өтүшү керек:

  1. HOME - колдонуучунун үй каталогу.
  2. LOGNAME — колдонуучунун кирүүсү.
  3. PATH стандарттык системанын утилиталарын таба турган жол.
  4. SHELL — колдонулган буйрук интерпретаторуна жол.

Белгилей кетсек, POSIX бул өзгөрмөлөрдүн маанилери кайдан келгени жөнүндө эч нерсе айтпайт.

Мыкты сатуучу - Vixie cron 3.0pl1

Популярдуу cron варианттарынын жалпы түпкү атасы 3.0-жылы comp.sources.unix почта тизмесине киргизилген Vixie cron 1pl1992. Бул версиянын негизги өзгөчөлүктөрүн кененирээк карап чыгабыз.

Vixie cron эки программада (cron жана crontab) келет. Адаттагыдай эле, демон системалык тапшырмалар таблицасынан жана жеке колдонуучу тапшырма таблицаларынан тапшырмаларды окуу жана иштетүү үчүн, ал эми crontab утилитасы колдонуучунун таблицаларын оңдоо үчүн жооптуу.

Тапшырма таблицасы жана конфигурация файлдары

Супер колдонуучу тапшырма таблицасы /etc/crontab ичинде жайгашкан. Системалык таблицанын синтаксиси Vixie cron синтаксисине туура келет, анын ичинен алтынчы тилкеде тапшырма аткарылган колдонуучунун аты көрсөтүлгөн:

# Запускается ежеминутно от пользователя vlad
* * * * * vlad /path/to/exec

Кадимки колдонуучу тапшырма таблицалары /var/cron/tabs/username ичинде жайгашкан жана ошол эле синтаксисти колдонушат. Колдонуучу катары crontab утилитасын иштеткенде, бул файлдар түзөтүлөт.

Crontabга кирүү мүмкүнчүлүгү бар колдонуучулардын тизмеси /var/cron/allow жана /var/cron/deny файлдарында башкарылат, мында жөн гана колдонуучунун атын өзүнчө сапка киргизиш керек.

Кеңейтилген синтаксис

POSIX crontab менен салыштырганда, Пол Виксинин чечими утилитанын тапшырма таблицаларынын синтаксисине бир нече абдан пайдалуу өзгөртүүлөрдү камтыйт.

Жадыбалдын жаңы синтаксиси жеткиликтүү болуп калды: мисалы, сиз аптанын күндөрүн же айларды аты менен белгилей аласыз (Дш, Шей, ж.б.):

# Запускается ежеминутно по понедельникам и вторникам в январе
* * * Jan Mon,Tue /path/to/exec

Сиз тапшырмалар ишке ашырыла турган кадамды белгилей аласыз:

# Запускается с шагом в две минуты
*/2 * * * Mon,Tue /path/to/exec

Кадамдар жана интервалдар аралаштырылышы мүмкүн:

# Запускается с шагом в две минуты в первых десять минут каждого часа
0-10/2 * * * * /path/to/exec

Кадимки синтаксиске интуитивдик альтернативалар колдоого алынат (кайра жүктөө, жыл сайын, жыл сайын, ай сайын, жума сайын, күн сайын, түн жарымында, саат сайын):

# Запускается после перезагрузки системы
@reboot /exec/on/reboot
# Запускается раз в день
@daily /exec/daily
# Запускается раз в час
@hourly /exec/daily

Тапшырманы аткаруу чөйрөсү

Vixie cron иштеп жаткан колдонмолордун чөйрөсүн өзгөртүүгө мүмкүндүк берет.

USER, LOGNAME жана HOME чөйрө өзгөрмөлөрү жөн гана демон тарабынан камсыз кылынбайт, бирок файлдан алынган passwd. PATH өзгөрмөсү "/usr/bin:/bin" жана SHELL өзгөрмөсү "/bin/sh" деп коюлган. LOGNAMEден башка бардык өзгөрмөлөрдүн маанилери колдонуучу таблицаларында өзгөртүлүшү мүмкүн.

Кээ бир чөйрө өзгөрмөлөрү (айрыкча SHELL жана HOME) тапшырманы аткаруу үчүн cron тарабынан колдонулат. Ыңгайлаштырылган тапшырмаларды аткаруу үчүн стандарттык sh ордуна bash колдонуу төмөнкүдөй болушу мүмкүн:

SHELL=/bin/bash
HOME=/tmp/
# exec будет запущен bash-ем в /tmp/
* * * * * /path/to/exec

Акыр-аягы, таблицада аныкталган бардык чөйрө өзгөрмөлөрү (cron тарабынан колдонулат же процесске керек) иштеп жаткан тапшырмага өткөрүлүп берилет.

Файлдарды түзөтүү үчүн crontab VISUAL же EDITOR чөйрө өзгөрмөсүндө көрсөтүлгөн редакторду колдонот. Эгерде crontab иштетилген чөйрөдө бул өзгөрмөлөр аныкталбаса, анда "/usr/ucb/vi" колдонулат (ucb, балким, Калифорния университети, Беркли).

Debian жана Ubuntu боюнча cron

Debian жана туунду бөлүштүрүүлөрдү иштеп чыгуучулар чыгарышты абдан өзгөртүлгөн версия Vixie cron версиясы 3.0pl1. Таблица файлдарынын синтаксисинде эч кандай айырмачылыктар жок, ал ошол эле Vixie cron. Эң чоң жаңы функция: Колдоо syslog, SELinux и АМПП.

Анча байкалбаган, бирок сезилерлик өзгөрүүлөр конфигурация файлдарынын жана тапшырма таблицаларынын жайгашкан жерин камтыйт.

Debianдагы колдонуучу таблицалары /var/spool/cron/crontabs каталогунда жайгашкан, системалык таблица дагы эле бар - /etc/crontab ичинде. Debian пакетине тиешелүү тапшырма таблицалары /etc/cron.d дарегине жайгаштырылат, ал жерден cron демону аларды автоматтык түрдө окуйт. Колдонуучунун мүмкүнчүлүгүн башкаруу /etc/cron.allow жана /etc/cron.deny файлдары тарабынан көзөмөлдөнөт.

Демейки кабык дагы эле /bin/sh болуп саналат, ал Debianда POSIX ылайыктуу кичинекей кабык. толкун, эч кандай конфигурацияны окубастан ишке киргизилген (интерактивдүү эмес режимде).

Cron өзү Debianдын эң акыркы версияларында systemd аркылуу ишке киргизилет жана ишке киргизүү конфигурациясын /lib/systemd/system/cron.service дарегинде көрүүгө болот. Кызматтын конфигурациясында өзгөчө эч нерсе жок; ар бир колдонуучунун кронтабасында түздөн-түз жарыяланган чөйрө өзгөрмөлөрүнүн жардамы менен кылдат тапшырманы башкарууга болот.

RedHat, Fedora жана CentOS боюнча cronie

cronie — Vixie cron версиясынын 4.1. Debianдагыдай эле синтаксис өзгөргөн жок, бирок PAM жана SELinux колдоо, кластерде иштөө, inotify аркылуу файлдарды көзөмөлдөө жана башка функциялар кошулду.

Демейки конфигурация кадимки жерлерде: системалык таблица /etc/crontab ичинде, пакеттер өз таблицаларын /etc/cron.d ичинде, колдонуучу таблицалары /var/spool/cron/crontabs ичинде.

Демон системалык көзөмөл астында иштейт, кызматтын конфигурациясы /lib/systemd/system/crond.service.

Red Hat сыяктуу бөлүштүрүүдө, /bin/sh демейки шартта ишке киргизүүдө колдонулат, бул стандарттуу bash. Белгилей кетчү нерсе, cron жумуштарын /bin/sh аркылуу иштеткенде, bash кабыгы POSIX ылайыктуу режимде башталат жана интерактивдүү эмес режимде иштеген эч кандай кошумча конфигурацияны окубайт.

SLES жана openSUSEдеги cronie

Германиянын SLES дистрибутиви жана анын туундусу openSUSE бир эле cronie колдонот. Бул жерде демон да systemd астында ишке киргизилген, кызматтын конфигурациясы /usr/lib/systemd/system/cron.service ичинде жайгашкан. Конфигурация: /etc/crontab, /etc/cron.d, /var/spool/cron/tabs. /bin/sh - бул POSIX шайкеш интерактивдүү эмес режимде иштеген ошол эле bash.

Vixie cron аппараты

Крондун заманбап урпактары Vixie cron менен салыштырганда түп-тамырынан бери өзгөргөн жок, бирок дагы эле программанын принциптерин түшүнүү үчүн талап кылынбаган жаңы функцияларга ээ болушту. Бул кеңейтүүлөрдүн көбү начар иштелип чыккан жана кодду чаташтырат. Пол Виксинин түпнуска cron булак коду окуудан ырахат алат.

Ошондуктан, мен cron түзмөгүн өнүктүрүүнүн эки тармагына тең жалпы cron программасынын мисалында талдоону чечтим - Vixie cron 3.0pl1. Окууну кыйындаткан ifdefтерди алып салуу жана майда деталдарды калтыруу менен мисалдарды жөнөкөйлөтөм.

жиндин иши бир нече этаптарга бөлүүгө болот:

  1. Программаны баштоо.
  2. Иштетүү үчүн тапшырмалардын тизмесин чогултуу жана жаңыртуу.
  3. Негизги cron цикли иштеп жатат.
  4. Тапшырма баштоо.

Келгиле, аларды ирети менен карап көрөлү.

Баштоо

Ишке киришкенде, процесстин аргументтерин текшергенден кийин, cron SIGCHLD жана SIGHUP сигнал иштеткичтерин орнотот. Биринчиси бала процессинин токтотулушу жөнүндө журналга жазуу киргизет, экинчиси журнал файлынын файл дескрипторун жабат:

signal(SIGCHLD, sigchld_handler);
signal(SIGHUP, sighup_handler);

Cron демон дайыма системада жалгыз иштейт, супер колдонуучу катары жана негизги cron каталогунан. Төмөнкү чалуулар демон процессинин PID'и менен кулпу файлын түзөт, колдонуучунун туура экенин текшерип, учурдагы каталогду негизгиге өзгөртөт:

acquire_daemonlock(0);
set_cron_uid();
set_cron_cwd();

Процесстерди баштоодо колдонула турган демейки жол коюлду:

setenv("PATH", _PATH_DEFPATH, 1);

Андан кийин процесс "демонизацияланат": ал процесстин бала көчүрмөсүн вилка жана бала процессинде жаңы сессияны (setsid чалуу) чакырып түзөт. Ата-энелик процесс мындан ары керек эмес жана ал чыгат:

switch (fork()) {
case -1:
    /* критическая ошибка и завершение работы */
    exit(0);
break;
case 0:
    /* дочерний процесс */
    (void) setsid();
break;
default:
    /* родительский процесс завершает работу */
    _exit(0);
}

Ата-энелик процесстин токтотулушу кулпу файлындагы кулпуну бошотот. Мындан тышкары, балага файлдагы PIDди жаңыртуу талап кылынат. Андан кийин, тапшырмалар базасы толтурулат:

/* повторный захват лока */
acquire_daemonlock(0);

/* Заполнение БД  */
database.head = NULL;
database.tail = NULL;
database.mtime = (time_t) 0;
load_database(&database);

Андан кийин cron негизги иш циклине өтөт. Бирок ага чейин тапшырмалар тизмесин жүктөөнү карап чыгуу керек.

Тапшырмалардын тизмесин чогултуу жана жаңыртуу

load_database функциясы тапшырмалардын тизмесин жүктөө үчүн жооптуу. Ал негизги системанын crontab жана колдонуучу файлдары менен каталогду текшерет. Эгерде файлдар жана каталог өзгөрбөсө, тапшырмалар тизмеси кайра окулбайт. Болбосо, милдеттердин жаңы тизмеси түзүлө баштайт.

Атайын файл жана таблица аттары менен тутумдук файлды жүктөө:

/* если файл системной таблицы изменился, перечитываем */
if (syscron_stat.st_mtime) {
    process_crontab("root", "*system*",
    SYSCRONTAB, &syscron_stat,
    &new_db, old_db);
}

Колдонуучу таблицаларын циклге жүктөө:

while (NULL != (dp = readdir(dir))) {
    char    fname[MAXNAMLEN+1],
            tabname[MAXNAMLEN+1];
    /* читать файлы с точкой не надо*/
    if (dp->d_name[0] == '.')
            continue;
    (void) strcpy(fname, dp->d_name);
    sprintf(tabname, CRON_TAB(fname));
    process_crontab(fname, fname, tabname,
                    &statbuf, &new_db, old_db);
}

Андан кийин эски маалымат базасы жаңысына алмаштырылат.

Жогорудагы мисалдарда process_crontab функциясынын чалуусу таблица файлынын атына дал келген колдонуучунун бар экенин текшерет (эгер ал супер колдонуучу болбосо), андан кийин load_user чакырат. Акыркысы файлдын өзүн сапка чейин окуйт:

while ((status = load_env(envstr, file)) >= OK) {
    switch (status) {
    case ERR:
        free_user(u);
        u = NULL;
        goto done;
    case FALSE:
        e = load_entry(file, NULL, pw, envp);
        if (e) {
            e->next = u->crontab;
            u->crontab = e;
        }
        break;
    case TRUE:
        envp = env_set(envp, envstr);
        break;
    }
}

Бул жерде же чөйрө өзгөрмөсү load_env / env_set функцияларын колдонуу менен орнотулат (VAR=маани формасындагы саптар), же load_entry функциясы аркылуу тапшырманын сүрөттөлүшү окулат (* * * * * /path/to/exec).

load_entry кайтарган жазуу объекти - бул тапшырмалардын жалпы тизмесине жайгаштырылган биздин милдет. Функциянын өзү убакыт форматын кеңири талдоону жүзөгө ашырат, бирок бизди айлана-чөйрөнүн өзгөрмөлөрүнүн жана тапшырманы ишке киргизүү параметрлеринин түзүлүшү көбүрөөк кызыктырат:

/* пользователь и группа для запуска задачи берутся из passwd*/
e->uid = pw->pw_uid;
e->gid = pw->pw_gid;

/* шелл по умолчанию (/bin/sh), если пользователь не указал другое */
e->envp = env_copy(envp);
if (!env_get("SHELL", e->envp)) {
    sprintf(envstr, "SHELL=%s", _PATH_BSHELL);
    e->envp = env_set(e->envp, envstr);
}
/* домашняя директория */
if (!env_get("HOME", e->envp)) {
    sprintf(envstr, "HOME=%s", pw->pw_dir);
    e->envp = env_set(e->envp, envstr);
}
/* путь для поиска программ */
if (!env_get("PATH", e->envp)) {
    sprintf(envstr, "PATH=%s", _PATH_DEFPATH);
    e->envp = env_set(e->envp, envstr);
}
/* имя пользовтеля всегда из passwd */
sprintf(envstr, "%s=%s", "LOGNAME", pw->pw_name);
e->envp = env_set(e->envp, envstr);

Негизги цикл учурдагы милдеттердин тизмеси менен иштейт.

Негизги цикл

7 Unix версиясынын түпнуска крону абдан жөнөкөй иштеди: ал конфигурацияны циклде кайра окуду, учурдагы мүнөттүн тапшырмаларын супер колдонуучу катары ишке киргизди жана кийинки мүнөттүн башталышына чейин уктады. Эски машиналарда бул жөнөкөй ыкма өтө көп ресурстарды талап кылган.

SysVде альтернативалуу версия сунушталды, анда демон же тапшырма аныкталган жакынкы мүнөткө чейин же 30 мүнөткө чейин уктап калган. Бул режимде конфигурацияны кайра окуу жана тапшырмаларды текшерүү үчүн ресурстар азыраак сарпталды, бирок тапшырмалардын тизмесин тез жаңыртуу ыңгайсыз болуп калды.

Vixie cron мүнөтүнө бир жолу тапшырмалардын тизмесин текшерүүгө кайтып келди, бактыга жараша, 80-жылдардын аягында стандарттуу Unix машиналарында ресурстар кыйла көп болгон:

/* первичная загрузка задач */
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 (ар бир тапшырманы аткаруу) функцияларын чакырат. Акыркы функция кененирээк карап чыгууга арзыйт.

Тапшырма аткаруу

do_command функциясы жакшы Unix стилинде аткарылат, башкача айтканда, тапшырманы асинхрондук түрдө аткаруу үчүн айры кылат. Ата-эне процесси тапшырмаларды баштоону улантат, бала процесси тапшырма процессин даярдайт:

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 менен келген версиянын кодун алуу бир сааттан ашпады жана мен абдан кызыктуу болдум! Мен аны сиз менен бөлүшө алдым деп үмүттөнөм.

Мен сизди билбейм, бирок заманбап программалоо өтө татаал жана абстракттуу тенденциясы менен көптөн бери мынчалык жөнөкөйлүккө шарт түзө электигин түшүнүп, бир аз капа болдум.

Cronдун көптөгөн заманбап альтернативалары бар: systemd-таймерлер көз карандылыктары бар татаал системаларды уюштурууга мүмкүндүк берет, fcron тапшырмалар боюнча ресурстарды керектөөнү ийкемдүү жөнгө салууга мүмкүндүк берет. Бирок жеке мен үчүн эң жөнөкөй crontab ар дайым жетиштүү болгон.

Кыскасы, Unixти сүйүңүз, жөнөкөй программаларды колдонуңуз жана платформаңыз үчүн мананы окууну унутпаңыз!

Source: www.habr.com

Комментарий кошуу