Cron në Linux: historia, përdorimi dhe struktura

Cron në Linux: historia, përdorimi dhe struktura

Klasicisti shkroi se orët e lumtura nuk vëzhgojnë. Në ato kohë të egra nuk kishte as programues, as Unix, por në ditët tona programuesit e dinë mirë: në vend të tyre, cron do të kujdeset për kohën.

Përgjigjet e linjës së komandës janë një dobësi dhe rutinë për mua. sed, awk, wc, cut dhe programe të tjera të vjetra aktivizohen përmes skripteve në serverat tanë çdo ditë. Shumica e tyre janë organizuar si detyra për cron, planifikuesin e lindur në vitet '70.

E kam përdorur cron sipërfaqësisht për një kohë të gjatë, pa u thelluar në detaje, por një herë, duke u përballur me një gabim gjatë ekzekutimit të një skripti, vendosa të merrem thellë me temën. Kështu lindi ky artikull, gjatë shkruarjes së të cilit u njohëm me POSIX crontab, variantet kryesore të cron në shpërndarjet e njohura të Linux dhe strukturën e disa prej tyre.

A përdorni Linux dhe aktivizoni detyra në cron? A jeni të interesuar në arkitekturën e aplikacioneve sistemore në Unix? Atëherë jemi në rrugë të njëjtë!

Përmbajtja

Origjina e llojeve

Ekzekutimi periodik i programeve përdoruesit ose sistemore është një nevojë e dukshme në të gjitha sistemet operative. Prandaj, nevoja për shërbime që lejojnë planifikimin dhe ekzekutimin qendror të detyrave është kuptuar prej programuesve shumë kohë më parë.

Sistemët operative të ngjashme me Unix kanë rrjedhjen e tyre nga Version 7 Unix, e zhvilluar në vitet '70 në Bell Labs, ndër të cilat dhe i famshmi Ken Thompson. Së bashku me Version 7 Unix u ofrua dhe cron, shërbimi për ekzekutimin e rregullt të detyrave të superpërdoruesit.

Një cron modern tipik është një program i thjeshtë, por algoritmi i funksionimit të variantit origjinal ishte edhe më i thjeshtë: shërbimi zgjoheshin një herë në minutë, lexonte tabelën me detyrat nga një skedar i vetëm (/etc/lib/crontab) dhe ekzekutonte për superpërdoruesin ato detyra që duhej të ekzekutoheshin në minutën aktuale.

Më pas, variantet e përmirësuara të këtij shërbimi të thjeshtë dhe të dobishëm erdhën me të gjitha sistemet operative të ngjashme me Unix.

Përshkrimet e përgjithshme të formatit crontab dhe parimet bazë të funksionimit të utilitarit u përfshinë në vitin 1992 në standardin kryesor të sistemëve operative të ngjashme me Unix — POSIX — dhe kështu cron nga standardi de facto u bë standardi de jure.

Në vitin 1987, Paul Vixie, pas një anketimi me përdorues të Unix për dëshirat e tyre në lidhje me cron, nxori një version tjetër të demonit që rregullonte disa probleme të cron tradicional dhe zgjeronte sintaksën e skedarëve të tabelave.

Me versionin e tretë, Vixie cron filloi të plotësonte kërkesat e POSIX, dhe programi kishte një licencë liberale, më saktë nuk kishte asnjë licencë, nëse nuk e konsiderojmë dëshirën në README: autori nuk jep garanci, emri i autorit nuk mund të hiqet, ndërsa programi mund të shitet vetëm bashkë me kodin burimor. Këto kërkesa ishin në përputhje me parimet e softuerit të lirë, që po fitonte popullaritet në ato vite, prandaj disa nga distribulet kryesore të Linux që u shfaqën në fillim të viteve '90 e përdorën Vixie cron si sistemin e tyre dhe e zhvillojnë akoma.

Në veçanti, Red Hat dhe SUSE zhvillojnë një fork të Vixie cron - cronie, ndërsa Debian dhe Ubuntu përdorin edicionin origjinal të Vixie cron me shumë patch-e.

Le të nisim duke u njohur me utilititetin e përdoruesit crontab të përshkruar në POSIX, pas të cilit do të shqyrtojmë zgjerimet e sintaksës, të paraqitura në Vixie cron, dhe përdorimin e variacioneve të Vixie cron në distribucione të njohura Linux. Dhe, në fund, i gjithë pluhuri - një analizë e mekanizmit të demonit cron.

POSIX crontab

Nëse cron origjinal gjithmonë punonte për superpërdoruesin, planifikuesit modernë shpesh merret me detyrat e përdoruesve të zakonshëm, që është më e sigurt dhe më e përshtatshme.

Cron-et vijnë si një paketë me dy programe: demonin e përhershëm cron dhe utilitetin crontab të disponueshëm për përdoruesit. Ky i fundit lejon redaktimin e tabelave të detyrave, specifike për çdo përdorues në sistem, ndërsa demoni ekzekuton detyrat nga tabelat e përdoruesve dhe tabelën sistematike.

standardi POSIX nuk e përshkruan sjelljen e demonit dhe formalizohet vetëm programi i përdoruesit crontab. Ekzistenca e mekanizmave për nisjen e detyrave të përdoruesve, sigurisht, nënkuptohet, por nuk është përshkruar në hollësi.

Me thirrjen e utilitetit crontab mund të bëni katër gjëra: të redaktoni tabelën e detyrave të përdoruesit në një editor, të ngarkoni tabelën nga një skedar, të tregoni tabelën aktuale të detyrave dhe të pastroni tabelën e detyrave. Shembuj të përdorimit të utilitetit crontab:

crontab -e # redaktoni tabelën e detyrave
crontab -l # tregoni tabelën e detyrave
crontab -r # fshini tabelën e detyrave
crontab path/to/file.crontab # ngarkoni tabelën e detyrave nga skedari

Kur thirret crontab -e do të përdoret redaktori i specifikuar në variablën standarde të mjedisit EDITOR.

Detyrat vetë përshkruhen në formatin e mëposhtëm:

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

Pesë fushat e para të regjistrimeve: minuta [1..60], orë [0..23], ditë të muajit [1..31], muaj [1..12], ditë të javës [0..6], ku 0 është e diela. Fushën e fundit, e gjashta, është një varg që do të ekzekutohet nga interpreti standard i komandave.

Në pesë fushat e para, vlerat mund të janë të listuara me presje:

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

Ose me ndarës:

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

Qasja e përdoruesve në planifikimin e detyrave rregullohet në skedarët POSIX cron.allow dhe cron.deny ku, përkatësisht, përmenden përdoruesit me akses në crontab dhe ata pa akses në program. Pozita e këtyre skedarëve standardi nuk e rregullon për asnjë mënyrë.

Programet që do të ekzekutohen, sipas standardit, duhet të marrin të paktën katër variabla mjedisi:

  1. HOME — direktoria e përdoruesit.
  2. LOGNAME — identifikuesi i përdoruesit.
  3. PATH — rruga ku mund të gjenden utilitarët standard të sistemit.
  4. SHELL — rruga për interpretorin e komandave të përdorur.

Është e rëndësishme të theksohet se POSIX nuk thotë asgjë lidhur me burimet e vlerave për këto variabla.

Shitja më e madhe — Vixie cron 3.0pl1

Paraardhësi i njohur i varianteve të famshme të cron — Vixie cron 3.0pl1, i prezantuar në dërgesën comp.sources.unix në vitin 1992. Ne do të shqyrtojmë më në detaje funksionalitetet kryesore të kësaj versioni.

Vixie cron ofrohet në dy programe (cron dhe crontab). Si zakonisht, demoni është përgjegjës për leximin dhe ekzekutimin e detyrave nga tabela sistemore e detyrave dhe tabelat e detyrave të përdoruesve individualë, ndërsa utilitarja crontab është përgjegjëse për redaktimin e tabelave të përdoruesve.

Tabela e detyrave dhe skedarët e konfigurimit

Tabela e detyrave të superpërdoruesit ndodhet në /etc/crontab. Sintaksa e tabelës sistemore correspndon me sintaksën e Vixie cron me një përjashtim që në kolonën e gjashtë përmendet emri i përdoruesit nga i cili ekzekutohet detyra:

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

Tabelat e detyrave të përdoruesve të zakonshëm ndodhen në /var/cron/tabs/username dhe përdorin sintaksë të përbashkët. Kur utilitarja crontab ndizet në emër të përdoruesit, redaktohen pikërisht këto skedarë.

Menaxhimi i listave të përdoruesve që kanë akses në crontab ndodh në skedarët /var/cron/allow dhe /var/cron/deny, në të cilat mjafton të shtohet emri i përdoruesit në një rresht të veçantë.

Sintaksa e zgjeruar

Në krahasim me POSIX crontab, zgjidhja e Paul Vixie përmban disa modifikime shumë të dobishme në sintaksën e tabelave të detyrave të utilitarit.

Një sintaksë e re për tabela është bërë e disponueshme: për shembull, mund të specifikoni të ditët e javës ose muajt me emër (Mon, Tue, etj.):

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

Mund të specifikoni hapin, përmes të cilit startohen detyrat:

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

Hapat dhe intervalet mund të përzihen:

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

Këto janë mbështetje për alternativa intuitive të sintaksës së zakonshme (reboot, yearly, annually, monthly, weekly, daily, midnight, hourly):

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

Mjedisi i ekzekutimit të detyrave

Vixie cron lejon të ndryshoni mjedisin e aplikacioneve të ekzekutuara.

Variablat e mjedisit USER, LOGNAME dhe HOME nuk ofrohen vetëm nga demoni, por merret nga skedari passwd. Variabli PATH merr vlerën "\/usr\/bin:\/bin", dhe SHELL është "\/bin\/sh". Të gjitha vlerat e variablave, përveç LOGNAME, mund të ndryshohen në tabelat e përdoruesve.

Disa variabla të mjedisit (përveç SHELL dhe HOME) përdoren nga vetë cron për të ekzekutuar detyrat. Ja si mund të duket përdorimi i bash në vend të sh--së standarde për të ekzekutuar detyrat e përdoruesve:

SHELL=\/bin\/bash
HOME=\/tmp\/\n# exec do të ekzekutohet me bash në \/tmp\/\n* * * * * \/path\/to\/exec

Në fund të fundit, të gjitha variablat e mjedisit të caktuar në tabelë (të përdorura nga cron ose të nevojshme për procesin) do të përcillen te detyra e ekzekutuar.

Për të redaktuar skedarët me utilitarin crontab, përdoret redaktori i përcaktuar në variablën e mjedisit VISUAL ose EDITOR. Nëse në mjedisin ku është ekzekutuar crontab, këto variabla nuk janë të caktuara, atëherë përdoret "\/usr\/ucb\/vi" (ucb ndoshta është University of California, Berkeley).

cron në Debian dhe Ubuntu

Zhvilluesit e Debian dhe distribucioneve të tij të derivuara kanë publikuar një version të modifikuar thellësisht versionin Vixie cron 3.0pl1. Nuk ka ndryshime në sintaksën e skedarëve të tabelës, për përdoruesit është i njëjti Vixie cron. Mundësitë më të mëdha të reja: mbështetje për syslog, SELinux dhe PAM.

Ndër ndryshimet më pak të dukshme, por të ndjeshme është vendndodhja e skedarëve të konfigurimit dhe tabelave të detyrave.

Tabelat e përdoruesve në Debian ndodhen në direktorinë \/var\/spool\/cron\/crontabs, tabela sistemore është ende në \/etc\/crontab. Tabelat e detyrave specifike për paketat Debian vendosen në \/etc\/cron.d, nga ku demoni cron i lexon ato automatikisht. Menaxhimi i aksesit të përdoruesve rregullohet nga skedarët \/etc\/cron.allow dhe \/etc\/cron.deny.

Si një shell default ende përdoret \/bin\/sh, në rolin e të cilit në Debian është një shell i vogël kompatibil me POSIX dash, i ekzekutuar pa lexuar asnjë konfiguracion (në modalitet jo-interaktiv).

Cron në versionet e fundit të Debian-it e запускается nga systemd, dhe konfigurimi i nisjes mund të shikohet në /lib/systemd/system/cron.service. Nuk ka asgjë të veçantë në konfigurimin e shërbimit, çdo menaxhim më i hollë i detyrave është i mundur përmes variablave të mjedisit të shpallur drejtpërdrejt në crontab për secilin përdorues.

cronie në RedHat, Fedora dhe CentOS

cronie — është një fork i Vixie cron versionit 4.1. Ashtu si në Debian, sintaksa nuk ka ndryshuar, por është shtuar mbështetje për PAM dhe SELinux, funksionimi në klaster, monitorimi i skedarëve me inotify dhe mundësi të tjera.

Konfigurimi i parazgjedhur ndodhet në vendet e zakonshme: tabela sistemore — në /etc/crontab, paketat vendosin tabelat e tyre në /etc/cron.d, tabelat e përdoruesve përfundojnë në /var/spool/cron/crontabs.

Demonin e drejton systemd, konfigurimi i shërbimit — /lib/systemd/system/crond.service.

Në shpërndarjet e ngjashme me Red Hat, kur niset në mënyrë të parazgjedhur përdoret /bin/sh, për të cilin është standardi bash. Duhet theksuar se kur detyrat cron iniciohen përmes /bin/sh, shell bash fillohet në modin në përputhje me POSIX dhe nuk lexon asnjë konfigurim shtesë, duke punuar në modin jo-interaktiv.

cronie në SLES dhe openSUSE

Distribucioni gjerman SLES dhe derivati i tij openSUSE përdorin të njëjtin cronie. Demon këtu gjithashtu aktivizohet nën systemd, konfigurimi i shërbimit ndodhet në /usr/lib/systemd/system/cron.service. Konfigurimi: /etc/crontab, /etc/cron.d, /var/spool/cron/tabs. Si /bin/sh përdoret i njëjti bash, i nisur në modin jo-interaktiv në përputhje me POSIX.

Struktura e Vixie cron

Pasardhësit modernë të cron në krahasim me Vixie cron nuk janë ndryshuar radikalisht, por megjithatë kanë fituar funksionalitete të reja, të cilat nuk janë të nevojshme për të kuptuar parimet e funksionimit të programit. Shumica e këtyre zgjerimeve janë formuar papërshtatshëm dhe ngatërrojnë kodin. Kodi origjinal burimor i cron nga Paul Vixie është një kënaqësi për ta lexuar.

Prandaj, unë vendosa të diskutoj strukturën e cron në shembujt e zakonshëm për të dyja degët e zhvillimit të programit — Vixie cron 3.0pl1. Do ta thjeshtoj shembujt, duke hequr ifdefët që e ndërlikojnë leximin dhe duke anashkaluar detajet e dyta.

Puna e demonit mund të ndahet në disa faza:

  1. Inicimi i programit.
  2. Mblidhen dhe përditësohen listat e detyrave për t'u ekzekutuar.
  3. Puna e ciklit kryesor të cron.
  4. Ekzekutimi i detyrës.

Le të i shqyrtojmë ato sipas rendit.

Inicimi

Kur fillon pas kontrollit të argumenteve, procesi cron vendos menaxherët e sinjaleve SIGCHLD dhe SIGHUP. I pari regjistron një hyrje për përfundimin e procesit fëmijë, ndërsa i dyti mbyll descriptorin e skedarit të logut:

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

Demonin cron në sistem gjithmonë funksionon si një, vetëm si superpërdorues dhe nga direktorja kryesore e cron. Thirrjet e mëposhtme krijojnë një skedar lock me PID-in e procesit demon, sigurohen që përdoruesi është i saktë dhe ndryshojnë direktorine aktuale në atë kryesore:

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

Përcaktohet rruga e paracaktuar që do të përdoret gjatë nisjes së proceseve:

setenv("PATH", _PATH_DEFPATH, 1);

Më pas procesi "demonizohet": krijon një kopje dytësore të procesit nga thirrja fork dhe një seancë të re në procesin fëmijë (thirrja setsid). Në procesin prind nuk ka më nevojë — dhe ai përfundon punën:

switch (fork()) {
case -1:
    \/\* gabim kritik dhe përfundimi i punës *\/\
    exit(0);
break;
case 0:
    \/\* procesi fëmijë *\/\
    (void) setsid();
break;
default:
    \/\* procesi prind përfundon punën *\/\
    _exit(0);
}

Përfundimi i procesit prind liro atë në skedarin lock. Për më tepër, kërkohet përditësimi i PID në skedarin në atë të fëmijës. Pas kësaj plotësohet baza e detyrave:

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

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

Më pas cron kalon në ciklin kryesor të punës. Por para kësaj, është mirë të shikoni ngarkesën e listës së detyrave.

Kthimi dhe përditësimi i listës së detyrave

Për ngarkimin e listës së detyrave është përgjegjëse funksioni load_database. Ai kontrollon crontab-in kryesor të sistemit dhe direktorinë me skedarët e përdoruesve. Nëse skedarët dhe direktorja nuk janë ndryshuar, lista e detyrave nuk rikthehet. Në rast të kundërt, fillon formimi i një liste të re detyrash.

Ngarkimi i skedarit sistemor me emra specifikë dhe tabela:

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

Ngarkimi i tabelave të përdoruesve në një cikël:

while (NULL != (dp = readdir(dir))) {
    char    fname[MAXNAMLEN+1],
            tabname[MAXNAMLEN+1];
    \/\* nuk duhet të lexohen skedarët që fillojnë me pikë *\/\
    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);
}

Pas kësaj, databaza e vjetër zëvendësohet me të re.

Në shembujt e mësipërm, thirrja e funksionit process_crontab sigurohet për ekzistencën e përdoruesit që i përket emrit të skedarit të tabelës (nëse kjo nuk është superpërdorues), pastaj thërret load_user. E fundit lexon vetë skedarin rresht pas rreshti:

ndërsa ((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;
    }
}

Këtu, ose vendoset një variabël mjedisore (vijat e llojit VAR=value) nga funksionet load_env / env_set, ose lexohen të dhënat e detyrës (*** *** *** /path/to/exec) nga funksioni load_entry.

Enti entry, që kthehet nga load_entry, është pikërisht detyra jonë, e sistemuar në listën e përbashkët të detyrave. Në funksion vetë bëhet një analizë e hollësishme e formatit të kohës, ndërsa ne jemi më të interesuar për formimin e variablave mjedisore dhe parametrave për ekzekutimin e detyrës:

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

Me listën aktuale të detyrave punon cikli kryesor.

Cikli kryesor

Kroni origjinal nga Version 7 Unix punonte shumë thjeshtë: në cikël rishtasi konfiguaracionin, ekzekutoi detyrat e minutës aktuale si superpërdorues dhe flinte deri në fillim të minutës tjetër. Ky qasje e thjeshtë në makinat e vjetra kërkonte shumë burime.

Në SysV u propozo një version alternativ, në të cilin demon flinte ose deri në minutën më të afërt për të cilën ishte caktuar një detyrë, apo për 30 minuta. Burimet për rishikimin e konfiguaracionit dhe kontrollimin e detyrave në këtë modalitet konsumoheshin më pak, por të përditësoje shpejt listën e detyrave bëhej epapërshkrueshme.

Vixie cron u kthye në kontrollimin e listës së detyrave çdo minutë, për fat të mirë deri në fund të viteve '80 burimet në makinat standarde Unix u rritën ndjeshëm:

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

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

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

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

Ekzekutimi i detyrave merret nga funksioni cron_sleep, që thërret funksionet job_runqueue (kalimi dhe ekzekutimi i detyrave) dhe do_command (ekzekutimi i çdo detyre individuale). Funksioni të fundit ia vlen të shqyrtohet më në detaje.

Ekzekutimi i detyrës

Funksioni do_command është shkruar në stil të mirë Unix, pra për ekzekutimin asinkron të detyrës ai bën fork. Procesi prind vazhdon të ekzekutojë detyrat, ndërsa ai fëmijor merret me përgatitjen e procesit të detyrës:

switch (fork()) {
case -1:
    /* nuk arriti të realizonte fork */
    break;
case 0:
    /* procesi fëmijor: për çdo rast bëjmë një herë tjetër për të kapur bllokimin kryesor */
    acquire_daemonlock(1);
    /* kalojmë në formimin e procesit të detyrës */
    child_process(e, u);
    /* në përfundim procesi fëmijor përfundon punën */
    _exit(OK_EXIT);
    break;
default:
    /* procesi prind vazhdon punën */
    break;
}

Në child_process ka shumë logjikë: ajo merr në dorë rrjedhat standarde të daljes dhe gabimeve për t'i dërguar më pas në email (nëse në tabelën e detyrave është e shënuar variabla e mjedisit MAILTO), dhe përfundimisht pret përfundimin e procesit kryesor të detyrës.

Procesi i detyrës formohet përmes një fork tjetër:

switch (vfork()) {
case -1:
    
    /* në rast gabimi, puna mbyllet menjëherë */
    exit(ERROR_EXIT);
case 0:
    /* procesi-në-nën formon një seancë të re, terminalin etj.
     */
    (void) setsid();

    /*
     * më poshtë ka një konfigurim të zgjatur të daljes së procesit, do ta kalojmë për shkak të shkurtësisë
     */

    /* ndryshimi i katalogut, përdoruesit dhe grupit të përdoruesit,
     * pra, procesi nuk është më si superpërdorues
     */
    setgid(e->gid);
    setuid(e->uid);
    chdir(env_get("HOME", e->envp));

    /* nisja e komandës vetë
     */
    {
        /* variabla e mjedisit SHELL tregon interpreterin për ekzekutimin */
        char    *shell = env_get("SHELL", e->envp);

        /* procesi niset pa transferimin e mjedisit të procesit prind,
         * pra, pikërisht siç përshkruhet në tabelën e detyrave të përdoruesit  */
        execle(shell, shell, "-c", e->cmd, (char *)0, e->envp);

        /* gabimi - dhe procesi nuk u nis? përfundimi i punës */
        perror("execl");
        _exit(ERROR_EXIT);
    }
    break;
default:
    /* vetë procesi vazhdon punën: pret përfundimin e punës dhe daljes */
    break;
}

Ja, përgjithësisht, e gjithë cron. Disa detaje interesante, siç është llogaritja e përdoruesve të largët, e kam lënë jashtë, por kam përshkruar të rëndësishmen.

Pasthënie

Cron - mrekullisht një program të thjeshtë dhe të dobishëm, zbatuar në traditat më të mira të botës Unix. Ai nuk bën asgjë të tepruar, por e bën punën e tij shkëlqyeshëm për shumë dekada tashmë. Njoftimi me kodin e asaj versioni që ofrohet me Ubuntu nuk zgjati më shumë se një orë, dhe kam fituar shumë kënaqësi! Shpresoj se kam arritur ta ndaj këtë me ju.

Nuk e di si jeni ju, por më bën pak të mërzitur të kuptoj se programimi modern me prirjen e tij për t'u komplikuar dhe për t'u ekzagjeruar nuk ofron prej kohësh thjeshtësinë e tillë.

Ekzistojnë shumë alternativa moderne për cron: sistemet systemd-timers lejojnë organizimin e sistemeve të komplikuara me varësi, tek fcron mund të rregullohet më fleksibël konsumimi i burimeve nga detyrat. Por personalisht, gjithmonë më ka mjaftuar crontab-i më i thjeshtë.

Në fjalë, duajeni Unix, përdorni programe të thjeshta dhe mos harroni të lexoni mamat për platformën tuaj!

Burimi: habr.com

Blini hostim të besueshëm për faqe interneti me mbrojtje DDoS, serverë VPS VDS 🔥 Blini hostim të besueshëm për faqe interneti me mbrojtje DDoS, serverë VPS VDS - ProHoster