Cron yn Linux: hanes, defnydd a dyfais

Cron yn Linux: hanes, defnydd a dyfais

Ysgrifennodd y clasur nad yw oriau hapus yn gwylio. Yn yr amseroedd gwyllt hynny nid oedd na rhaglenwyr nac Unix, ond heddiw mae rhaglenwyr yn gwybod yn sicr: bydd cron yn cadw golwg ar amser yn eu lle.

Mae cyfleustodau llinell orchymyn yn wendid ac yn faich i mi. Mae sed, awk, wc, cut a hen raglenni eraill yn cael eu rhedeg gan sgriptiau ar ein gweinyddion bob dydd. Mae llawer ohonynt wedi'u cynllunio fel tasgau ar gyfer cron, rhaglennydd sy'n wreiddiol o'r 70au.

Am gyfnod hir defnyddiais cron yn arwynebol, heb fynd i fanylion, ond un diwrnod, pan ddeuthum ar draws gwall wrth redeg sgript, penderfynais edrych i mewn iddo'n drylwyr. Dyma sut yr ymddangosodd yr erthygl hon, wrth ei hysgrifennu deuthum yn gyfarwydd â POSIX crontab, y prif opsiynau cron mewn dosbarthiadau Linux poblogaidd a strwythur rhai ohonynt.

Ydych chi'n defnyddio Linux ac yn rhedeg tasgau cron? Oes gennych chi ddiddordeb mewn pensaernïaeth cymhwysiad system yn Unix? Yna rydyn ni ar ein ffordd!

Cynnwys

Tarddiad rhywogaeth

Mae gweithredu rhaglenni defnyddwyr neu systemau o bryd i'w gilydd yn anghenraid amlwg ym mhob system weithredu. Felly, sylweddolodd rhaglenwyr yr angen am wasanaethau sy'n caniatáu iddynt gynllunio a chyflawni tasgau yn ganolog amser maith yn ôl.

Mae systemau gweithredu tebyg i Unix yn olrhain eu gwreiddiau yn ôl i Fersiwn 7 Unix, a ddatblygwyd yn 70au'r ganrif ddiwethaf yn Bell Labs, gan gynnwys gan yr enwog Ken Thompson. Roedd Fersiwn 7 Unix hefyd yn cynnwys cron, gwasanaeth ar gyfer rhedeg tasgau uwch-ddefnyddwyr yn rheolaidd.

Mae cron modern nodweddiadol yn rhaglen syml, ond roedd algorithm gweithredu'r fersiwn wreiddiol hyd yn oed yn symlach: deffrodd y gwasanaeth unwaith y funud, darllenwch dabl gyda thasgau o un ffeil (/etc/lib/crontab) a pherfformiwyd ar gyfer y superuser y tasgau hynny a ddylai fod wedi'u cyflawni ar hyn o bryd.

O ganlyniad, darparwyd fersiynau gwell o'r gwasanaeth syml a defnyddiol gyda'r holl systemau gweithredu tebyg i Unix.

Roedd disgrifiadau cyffredinol o fformat crontab ac egwyddorion sylfaenol gweithrediad y cyfleustodau wedi'u cynnwys ym mhrif safon systemau gweithredu tebyg i Unix - POSIX - ym 1992, ac felly daeth cron o safon de facto yn safon de jure.

Yn 1987, rhyddhaodd Paul Vixie, ar ôl arolygu defnyddwyr Unix am eu dymuniadau ar gyfer cron, fersiwn arall o'r daemon a oedd yn cywiro rhai o broblemau cron traddodiadol ac yn ehangu cystrawen ffeiliau tabl.

Erbyn trydydd fersiwn Vixie cron dechreuodd fodloni gofynion POSIX, yn ogystal, roedd gan y rhaglen drwydded ryddfrydol, neu yn hytrach nid oedd unrhyw drwydded o gwbl, ac eithrio'r dymuniadau yn y README: nid yw'r awdur yn rhoi gwarantau, enw'r awdur Ni ellir ei ddileu, a dim ond gyda chod ffynhonnell y gellir gwerthu'r rhaglen. Trodd y gofynion hyn yn gydnaws ag egwyddorion meddalwedd am ddim a oedd yn dod yn fwy poblogaidd yn y blynyddoedd hynny, felly cymerodd rhai o'r dosbarthiadau Linux allweddol a ymddangosodd yn y 90au cynnar Vixie cron fel eu system un ac maent yn dal i'w datblygu heddiw.

Yn benodol, mae Red Hat a SUSE yn datblygu fforc o Vixie cron - cronie, ac mae Debian a Ubuntu yn defnyddio'r rhifyn gwreiddiol o Vixie cron gyda llawer o glytiau.

Yn gyntaf, gadewch i ni ddod yn gyfarwydd â'r crontab cyfleustodau defnyddiwr a ddisgrifir yn POSIX, ac ar ôl hynny byddwn yn edrych ar yr estyniadau cystrawen a ddarperir yn Vixie cron a'r defnydd o amrywiadau o Vixie cron mewn dosbarthiadau Linux poblogaidd. Ac yn olaf, y ceirios ar y gacen yw'r dadansoddiad o'r ddyfais daemon cron.

crontab POSIX

Pe bai'r cron gwreiddiol bob amser yn gweithio i'r superuser, mae amserlenwyr modern yn aml yn delio â thasgau defnyddwyr cyffredin, sy'n fwy diogel a chyfleus.

Mae Crons yn cael eu cyflenwi fel set o ddwy raglen: yr ellyll cron sy'n rhedeg yn gyson a'r cyfleustodau crontab sydd ar gael i ddefnyddwyr. Mae'r olaf yn caniatáu ichi olygu tablau tasg sy'n benodol i bob defnyddiwr yn y system, tra bod yr ellyll yn lansio tasgau o dablau defnyddwyr a system.

В safon POSIX nid yw ymddygiad yr ellyll yn cael ei ddisgrifio mewn unrhyw ffordd a dim ond y rhaglen defnyddiwr sy'n cael ei ffurfioli crontab. Mae bodolaeth mecanweithiau ar gyfer lansio tasgau defnyddwyr, wrth gwrs, yn cael ei awgrymu, ond nid yw wedi'i ddisgrifio'n fanwl.

Trwy ffonio'r cyfleustodau crontab, gallwch chi wneud pedwar peth: golygu tabl tasgau defnyddiwr yn y golygydd, llwytho tabl o ffeil, dangos y tabl tasgau cyfredol, a chlirio'r tabl tasgau. Enghreifftiau o sut mae cyfleustodau crontab yn gweithio:

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

Wrth alw crontab -e bydd y golygydd a nodir yn y newidyn amgylchedd safonol yn cael ei ddefnyddio EDITOR.

Disgrifir y tasgau eu hunain yn y fformat a ganlyn:

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

Pum maes cyntaf y cofnodion: munudau [1..60], oriau [0..23], dyddiau'r mis [1...31], misoedd [1..12], dyddiau'r wythnos [0. .6], lie 0 yw Sul. Mae'r maes olaf, chweched, yn llinell a fydd yn cael ei gweithredu gan y cyfieithydd gorchymyn safonol.

Yn y pum maes cyntaf, gellir rhestru gwerthoedd wedi'u gwahanu gan atalnodau:

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

Neu gyda chysylltnod:

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

Mae mynediad defnyddwyr i amserlennu tasgau yn cael ei reoleiddio yn POSIX gan y ffeiliau cron.allow a cron.deny, sy'n rhestru defnyddwyr sydd â mynediad i crontab a defnyddwyr heb fynediad i'r rhaglen, yn y drefn honno. Nid yw'r safon yn rheoleiddio lleoliad y ffeiliau hyn mewn unrhyw ffordd.

Yn ôl y safon, rhaid trosglwyddo o leiaf bedwar newidyn amgylchedd i raglenni a lansiwyd:

  1. CARTREF - cyfeiriadur cartref y defnyddiwr.
  2. LOGNAME — mewngofnodi defnyddiwr.
  3. PATH yw'r llwybr lle gallwch ddod o hyd i gyfleustodau system safonol.
  4. SHELL - llwybr i'r dehonglydd gorchymyn a ddefnyddir.

Yn nodedig, nid yw POSIX yn dweud dim am o ble mae'r gwerthoedd ar gyfer y newidynnau hyn yn dod.

Gwerthwr gorau - Vixie cron 3.0pl1

Cyndad cyffredin amrywiadau cron poblogaidd yw Vixie cron 3.0pl1, a gyflwynwyd yn rhestr bostio comp.sources.unix ym 1992. Byddwn yn ystyried prif nodweddion y fersiwn hon yn fwy manwl.

Daw Vixie cron mewn dwy raglen (cron a crontab). Yn ôl yr arfer, mae'r daemon yn gyfrifol am ddarllen a rhedeg tasgau o'r tabl tasgau system a thablau tasgau defnyddwyr unigol, ac mae'r cyfleustodau crontab yn gyfrifol am olygu tablau defnyddwyr.

Tabl tasg a ffeiliau ffurfweddu

Mae'r tabl tasgau superuser wedi'i leoli yn /etc/crontab. Mae cystrawen y tabl system yn cyfateb i gystrawen Vixie cron, ac eithrio bod y chweched golofn ynddo'n nodi enw'r defnyddiwr y mae'r dasg yn cael ei lansio ar ei ran:

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

Mae tablau tasg defnyddiwr rheolaidd wedi'u lleoli yn /var/cron/tabs/username ac yn defnyddio'r un gystrawen. Pan fyddwch chi'n rhedeg y cyfleustodau crontab fel defnyddiwr, dyma'r ffeiliau sy'n cael eu golygu.

Mae'r rhestrau o ddefnyddwyr sydd â mynediad at crontab yn cael eu rheoli yn y ffeiliau /var/cron/allow a /var/cron/deny, lle mae angen i chi nodi'r enw defnyddiwr mewn llinell ar wahân yn unig.

Cystrawen estynedig

O'i gymharu â crontab POSIX, mae datrysiad Paul Vixey yn cynnwys nifer o addasiadau defnyddiol iawn i gystrawen tablau tasg y cyfleustodau.

Mae cystrawen tabl newydd wedi dod ar gael: er enghraifft, gallwch chi nodi dyddiau'r wythnos neu fisoedd yn ôl enw (Llun, Maw, ac ati):

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

Gallwch chi nodi'r cam ar gyfer lansio tasgau:

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

Gellir cymysgu camau ac ysbeidiau:

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

Cefnogir dewisiadau sythweledol i'r gystrawen arferol (ailgychwyn, blynyddol, blynyddol, misol, wythnosol, dyddiol, hanner nos, bob awr):

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

Amgylchedd cyflawni tasgau

Mae Vixie cron yn caniatáu ichi newid amgylchedd rhedeg cymwysiadau.

Nid yr ellyll yn unig sy'n darparu'r newidynnau amgylchedd USER, LOGNAME a HOME, ond fe'u cymerir o ffeil passwd. Mae'r newidyn PATH wedi'i osod i "/usr/bin:/bin" ac mae'r newidyn SHELL wedi'i osod i "/ bin/sh". Gellir newid gwerthoedd pob newidyn ac eithrio LOGNAME mewn tablau defnyddwyr.

Mae cron ei hun yn defnyddio rhai newidynnau amgylchedd (SHELL a HOME yn fwyaf arbennig) i redeg y dasg. Dyma sut olwg fyddai ar ddefnyddio bash yn lle sh safonol i redeg tasgau arferol:

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

Yn y pen draw, bydd yr holl newidynnau amgylchedd a ddiffinnir yn y tabl (a ddefnyddir gan cron neu sydd eu hangen gan y broses) yn cael eu trosglwyddo i'r dasg redeg.

I olygu ffeiliau, mae crontab yn defnyddio'r golygydd a nodir yn y newidyn amgylchedd VISUAL neu EDITOR. Os nad yw'r newidynnau hyn wedi'u diffinio yn yr amgylchedd lle cafodd crontab ei redeg, yna defnyddir "/usr/ucb/vi" (mae'n debyg mai Prifysgol California, Berkeley yw ucb).

cron ar Debian a Ubuntu

Mae datblygwyr Debian a dosbarthiadau deilliadol wedi rhyddhau fersiwn wedi'i addasu'n fawr Vixie cron fersiwn 3.0pl1. Nid oes unrhyw wahaniaethau yng nghstrawen ffeiliau tabl; i ddefnyddwyr yr un peth yw Vixie cron. Nodwedd Newydd Fwyaf: Cefnogaeth syslog, SELinux и PAM.

Mae newidiadau llai amlwg, ond diriaethol, yn cynnwys lleoliad ffeiliau ffurfweddu a thablau tasg.

Mae tablau defnyddwyr yn Debian wedi'u lleoli yn y cyfeiriadur /var/spool/cron/crontabs, mae tabl y system yn dal i fod yno - yn /etc/crontab. Rhoddir tablau tasg penodol i becyn Debian yn /etc/cron.d, lle mae'r daemon cron yn eu darllen yn awtomatig. Rheolir rheolaeth mynediad defnyddwyr gan y ffeiliau /etc/cron.allow a /etc/cron.deny.

Y gragen ddiofyn yw /bin/sh o hyd, sydd yn Debian yn gragen fach sy'n cydymffurfio â POSIX llinell doriad, wedi'i lansio heb ddarllen unrhyw ffurfweddiad (yn y modd nad yw'n rhyngweithiol).

Mae Cron ei hun yn y fersiynau diweddaraf o Debian yn cael ei lansio trwy systemd, a gellir gweld y cyfluniad lansio yn /lib/systemd/system/cron.service. Nid oes dim byd arbennig yng nghyfluniad y gwasanaeth; gellir gwneud unrhyw waith rheoli tasg mwy cynnil trwy newidynnau amgylchedd a ddatganwyd yn uniongyrchol yn crontab pob defnyddiwr.

cronie ar RedHat, Fedora a CentOS

cronie — fforc o Vixie cron fersiwn 4.1. Fel yn Debian, nid yw'r gystrawen wedi newid, ond mae cefnogaeth i PAM a SELinux, gan weithio mewn clwstwr, olrhain ffeiliau gan ddefnyddio inotify a nodweddion eraill wedi'u hychwanegu.

Mae'r cyfluniad rhagosodedig yn y mannau arferol: mae tabl y system yn /etc/crontab, mae pecynnau'n rhoi eu tablau yn /etc/cron.d, mae tablau defnyddwyr yn mynd i mewn /var/spool/cron/crontabs.

Mae'r daemon yn rhedeg o dan reolaeth systemd, cyfluniad y gwasanaeth yw /lib/systemd/system/crond.service.

Ar ddosbarthiadau tebyg i Red Hat, defnyddir /bin/sh yn ddiofyn wrth gychwyn, sef y bash safonol. Dylid nodi, wrth redeg swyddi cron trwy / bin / sh, bod y gragen bash yn dechrau yn y modd sy'n cydymffurfio â POSIX ac nid yw'n darllen unrhyw ffurfweddiad ychwanegol, gan redeg yn y modd nad yw'n rhyngweithiol.

cronie yn SLES ac openSUSE

Mae'r dosbarthiad Almaeneg SLES a'i ddeilliad openSUSE yn defnyddio'r un cronie. Mae'r daemon yma hefyd yn cael ei lansio o dan systemd, mae ffurfweddiad y gwasanaeth wedi'i leoli yn /usr/lib/systemd/system/cron.service. Ffurfweddiad: /etc/crontab, /etc/cron.d, /var/spool/cron/tabs. Mae / bin/sh yr un bash yn rhedeg yn y modd nad yw'n cydymffurfio â POSIX.

dyfais cron Vixie

Nid yw disgynyddion modern cron wedi newid yn radical o'i gymharu â Vixie cron, ond maent yn dal i gaffael nodweddion newydd nad oes eu hangen i ddeall egwyddorion y rhaglen. Mae llawer o'r estyniadau hyn wedi'u cynllunio'n wael ac yn drysu'r cod. Mae'r cod ffynhonnell cron gwreiddiol gan Paul Vixey yn bleser i'w ddarllen.

Felly, penderfynais ddadansoddi'r ddyfais cron gan ddefnyddio'r enghraifft o raglen cron sy'n gyffredin i'r ddwy gangen o ddatblygiad - Vixie cron 3.0pl1. Byddaf yn symleiddio'r enghreifftiau drwy ddileu idefs sy'n cymhlethu darllen a hepgor mân fanylion.

Gellir rhannu gwaith y cythraul yn sawl cam:

  1. Cychwyn rhaglen.
  2. Casglu a diweddaru'r rhestr o dasgau i'w rhedeg.
  3. Prif ddolen cron yn rhedeg.
  4. Dechrau tasg.

Gadewch i ni edrych arnynt mewn trefn.

Cychwyn

Pan ddechreuwyd, ar ôl gwirio'r dadleuon proses, mae cron yn gosod y trinwyr signal SIGCHLD a SIGHUP. Mae'r un cyntaf yn gwneud cofnod log am derfynu'r broses plentyn, mae'r ail yn cau disgrifydd ffeil y ffeil log:

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

Mae'r daemon cron bob amser yn rhedeg ar ei ben ei hun ar y system, dim ond fel uwch-ddefnyddiwr ac o'r prif gyfeiriadur cron. Mae'r galwadau canlynol yn creu ffeil clo gyda PID y broses daemon, gwnewch yn siŵr bod y defnyddiwr yn gywir a newidiwch y cyfeiriadur cyfredol i'r prif un:

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

Mae'r llwybr rhagosodedig wedi'i osod, a fydd yn cael ei ddefnyddio wrth gychwyn prosesau:

setenv("PATH", _PATH_DEFPATH, 1);

Yna mae'r broses yn cael ei “daemonized”: mae'n creu copi plentyn o'r broses trwy fforch galw a sesiwn newydd yn y broses plentyn (call setiauid). Nid oes angen y broses rhiant bellach, ac mae'n gadael:

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

Mae terfynu'r broses rhiant yn rhyddhau'r clo ar y ffeil clo. Yn ogystal, mae'n ofynnol diweddaru'r PID yn y ffeil i'r plentyn. Ar ôl hyn, mae'r gronfa ddata tasgau wedi'i llenwi i mewn:

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

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

Yna mae cron yn symud ymlaen i'r prif gylchred gwaith. Ond cyn hynny, mae'n werth edrych ar lwytho'r rhestr dasgau.

Casglu a diweddaru'r rhestr dasgau

Mae'r swyddogaeth load_database yn gyfrifol am lwytho'r rhestr o dasgau. Mae'n gwirio crontab y brif system a'r cyfeiriadur gyda ffeiliau defnyddwyr. Os nad yw'r ffeiliau a'r cyfeiriadur wedi newid, ni chaiff y rhestr dasgau ei hail-ddarllen. Fel arall, mae rhestr newydd o dasgau yn dechrau ffurfio.

Llwytho ffeil system gydag enwau ffeil a thabl arbennig:

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

Wrthi'n llwytho tablau defnyddwyr mewn dolen:

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);
}

Ar ôl hynny mae'r hen gronfa ddata yn cael ei disodli gan un newydd.

Yn yr enghreifftiau uchod, mae galwad swyddogaeth process_crontab yn gwirio bod defnyddiwr sy'n cyfateb i'r enw ffeil tabl yn bodoli (oni bai ei fod yn uwch-ddefnyddiwr) ac yna'n galw load_user. Mae'r olaf eisoes yn darllen y ffeil ei hun fesul llinell:

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;
    }
}

Yma, naill ai gosodir y newidyn amgylchedd (llinellau o'r ffurf VAR=value) gan ddefnyddio'r swyddogaethau load_env / env_set, neu darllenir y disgrifiad tasg (* * * * * /path/to/exec) gan ddefnyddio'r swyddogaeth load_entry.

Yr endid mynediad y mae load_entry yn ei ddychwelyd yw ein tasg, sy'n cael ei roi yn y rhestr gyffredinol o dasgau. Mae'r swyddogaeth ei hun yn dosrannu'r fformat amser ar lafar, ond mae gennym fwy o ddiddordeb mewn ffurfio newidynnau amgylchedd a pharamedrau lansio tasg:

/* пользователь и группа для запуска задачи берутся из 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);

Mae'r brif ddolen yn gweithio gyda'r rhestr gyfredol o dasgau.

Prif Ddolen

Gweithiodd y cron gwreiddiol o Fersiwn 7 Unix yn eithaf syml: fe ail-ddarllenodd y cyfluniad mewn dolen, lansiodd dasgau'r funud gyfredol fel superuser, a chysgu tan ddechrau'r funud nesaf. Roedd angen gormod o adnoddau ar y dull syml hwn ar beiriannau hŷn.

Cynigiwyd fersiwn amgen yn SysV, lle aeth yr ellyll i gysgu naill ai tan y funud agosaf y diffiniwyd y dasg ar ei chyfer, neu am 30 munud. Defnyddiwyd llai o adnoddau ar gyfer ailddarllen y ffurfweddiad a gwirio tasgau yn y modd hwn, ond daeth diweddaru'r rhestr o dasgau yn gyflym yn anghyfleus.

Dychwelodd Vixie cron i wirio rhestrau tasgau unwaith y funud, yn ffodus erbyn diwedd yr 80au roedd llawer mwy o adnoddau ar beiriannau Unix safonol:

/* первичная загрузка задач */
load_database(&database);
/* запустить задачи, поставленные к выполнению после перезагрузки системы */
run_reboot_jobs(&database);
/* сделать TargetTime началом ближайшей минуты */
cron_sync();
while (TRUE) {
    /* выполнить задачи, после чего спать до TargetTime с поправкой на время, потраченное на задачи */
    cron_sleep();

    /* перечитать конфигурацию */
    load_database(&database);

    /* собрать задачи для данной минуты */
    cron_tick(&database);

    /* перевести TargetTime на начало следующей минуты */
    TargetTime += 60;
}

Mae'r swyddogaeth cron_sleep yn ymwneud yn uniongyrchol â chyflawni tasgau, gan alw'r swyddogaethau job_runqueue (rhifo a rhedeg tasgau) a do_command (rhedeg pob tasg unigol). Mae'n werth archwilio'r swyddogaeth olaf yn fanylach.

Rhedeg tasg

Mae'r swyddogaeth do_command yn cael ei gweithredu mewn arddull Unix da, hynny yw, mae'n fforchio i gyflawni'r dasg yn asyncronig. Mae'r broses rhiant yn parhau i lansio tasgau, mae'r broses plentyn yn paratoi'r broses dasg:

switch (fork()) {
case -1:
    /*не смогли выполнить fork */
    break;
case 0:
    /* дочерний процесс: на всякий случай еще раз пробуем захватить главный лок */
    acquire_daemonlock(1);
    /* переходим к формированию процесса задачи */
    child_process(e, u);
    /* по завершению дочерний процесс заканчивает работу */
    _exit(OK_EXIT);
    break;
default:
    /* родительский процесс продолжает работу */
    break;
}

Mae cryn dipyn o resymeg yn child_process: mae'n cymryd ffrydiau allbwn a gwall safonol arno'i hun, er mwyn ei anfon i'r post (os yw'r newidyn amgylchedd MAILTO wedi'i nodi yn y tabl tasgau), ac, yn olaf, yn aros am y prif broses y dasg i'w chwblhau.

Mae'r broses dasg yn cael ei ffurfio gan fforc arall:

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;
}

Dyna yn y bôn holl cron yw. Hepgorais rai manylion diddorol, er enghraifft, cyfrif am ddefnyddwyr o bell, ond amlinellais y prif beth.

Afterword

Mae Cron yn rhaglen rhyfeddol o syml a defnyddiol, wedi'i gwneud yn nhraddodiadau gorau'r byd Unix. Nid yw hi'n gwneud dim byd ychwanegol, ond mae hi wedi bod yn gwneud ei gwaith yn wych ers sawl degawd bellach. Ni chymerodd mynd trwy'r cod ar gyfer y fersiwn sy'n dod gyda Ubuntu mwy nag awr, a chefais lawer o hwyl! Rwy'n gobeithio fy mod wedi gallu ei rannu gyda chi.

Wn i ddim amdanoch chi, ond rydw i braidd yn drist i sylweddoli nad yw rhaglennu modern, gyda'i duedd i or-gymhlethu a gor-haniaethol, wedi bod yn ffafriol i symlrwydd o'r fath ers amser maith.

Mae yna lawer o ddewisiadau modern yn lle cron: mae amseryddion systemd yn caniatáu ichi drefnu systemau cymhleth gyda dibyniaethau, mae fcron yn caniatáu ichi reoleiddio'r defnydd o adnoddau fesul tasgau yn fwy hyblyg. Ond yn bersonol, roedd y crontab symlaf bob amser yn ddigon i mi.

Yn fyr, cariad Unix, defnyddiwch raglenni syml a pheidiwch ag anghofio darllen y mana ar gyfer eich platfform!

Ffynhonnell: hab.com

Ychwanegu sylw