Cron Linuxis: ajalugu, kasutamine ja struktuur

Cron Linuxis: ajalugu, kasutamine ja struktuur

Klassik kirjutas, et õnnelikke tunde ei jälgita. Neil metsikudel aegadel ei olnud ei programmeerijaid ega Unixit, aga tänapäeval teavad programmeerijad kindlalt: nende eest jälgib aega cron.

Käsklusrida utiliidid on mulle samal ajal nõrkus ja rutiin. sed, awk, wc, cut ja teised vanad programmid käivituvad meie serverites igapäevaselt skriptide kaudu. Paljud neist on vormistatud cron'i ülesannetena, ajakava, mis pärineb 70-ndatest.

Ma kasutasin pikka aega cron'i pinnapealselt, süvenemata detailidesse, kuid ühel päeval, kui kohtusin skripti käitamise vea tõttu probleemiga, otsustasin asja põhjalikult uurida. Nii sündis see artikkel, mille kirjutamise ajal tutvusin POSIX crontab'i, populaarsete Linuxi distributsioonide cron'i peamiste variatsioonide ja mõnede nende tööpõhimõtetega.

Kasutad Linuxit ja käivitad cron'is ülesandeid? Kas sind huvitab süsteemsete rakenduste arhitektuur Unixis? Siis oleme õigel teel!

Sisukord

Liikide päritolu

Kasutaja- või süsteemiprogrammide perioodiline käivitamine on igas operatsioonisüsteemis ilmne vajadus. Seetõttu mõistsid programmeerijad ammu vajadust teenuste järele, mis võimaldavad keskelt planeerida ja täita ülesandeid.

Unixitaolised operatsioonisüsteemid saavad oma päritolu Version 7 Unix'ist, mis loodi 70-ndatel aastatel Bell Labs'is, sealhulgas kuulus Ken Thompson (ingl. k. Ken Thompson). Koos Version 7 Unix'iga kaasnes ka cron, teenus, mis tagab superkasutaja ülesannete regulaarse täitmise.

Tüüpiline kaasaegne cron on lihtne programm, kuid algse variandi tööalgrütm oli veelgi lihtsam: teenus ärkas kord minutis, luges ülesannete tabelit ainukesest failist (\/etc\/lib\/crontab) ja täitis superkasutaja ülesandeid, mis pidid käima praegusel minutil.

Hiljem täiustatud variandid sellest lihtsast ja kasulikust teenusest saadeti kõikide Unix-taoliste operatsioonisüsteemidega.

Üldised kirjeldused crontab'i vormingust ja utiliidi põhimõistetest lisati 1992. aastal Unix-taoliste operatsioonisüsteemide peamisse standardisse — POSIX — ja seega muutus cron de facto standardist de jure standardiks.

1987. aastal küsitles Paul Vixie Unix'i kasutajaid cron'i soovide osas ja avaldas veel ühe daemon'i versiooni, mis lahendas traditsioonilise cron'i probleeme ja laiendas tabelifailide süntaksit.

Kolmanda versiooni puhul vastas Vixie cron POSIX'i nõuetele ning programm oli vabalt kasutatav, tegelikult ei olnud seal ühtegi litsentsi, välja arvatud soovitused README-s: autor ei anna mingeid garantiisid, autori nime ei tohi eemaldada ja programmi võib müüa ainult koos lähtekoodiga. Need nõudmised osutusid harmoneerituks toona populaarsust kogunud avatud tarkvara põhimõtetega, seetõttu võtsid mitmed 90ndate alguses ilmunud Linux'i distributsioonid Vixie cron'i süsteemi osaks ja arendavad seda siiani.

Eelkõige arendavad Red Hat ja SUSE Vixie cron'i fork'i — cronie, samas kui Debian ja Ubuntu kasutavad originaalversiooni Vixie cron'ist, millel on palju plaastreid.

Tutvume alguses POSIX'is kirjeldatud kasutaja tööriistaga crontab, seejärel vaatame Vixie cron'i esitatud süntaksi laiendusi ja Vixie cron'i variatsioonide kasutamist populaarses Linux'i distributsioonides. Ja lõpuks, tordi kirsina — cron daemon'i ülesehituse analüüs.

POSIX crontab

Kui originaal cron töötas alati superkasutaja jaoks, siis kaasaegsed ajakava koostajad tegelevad enamasti tavaliste kasutajate ülesannetega, mis on turvalisem ja mugavam.

Cron'id koosnevad kahest programmist: pidevalt töötavast cron demon'ist ja kasutajatele kergesti kättesaadavast crontab utiliidist. Viimane võimaldab redigeerida süsteemi iga kasutaja spetsiifilisi ülesandeid, demon aga käivitab ülesandeid nii kasutaja kui ka süsteemi tabelitest.

Uues POSIX'i standard ei kirjeldata demon'i käitumist, vaid ainult kasutaja programmi formaalsed aspektid. crontab. Loomulikult eeldatakse, et on olemas mehhanismid kasutaja ülesannete käivitamiseks, kuid neid ei ole detailselt kirjeldatud.

Crontab utiliidi kutsumisega saab teha neli asja: redigeerida oma ülesannete tabelit redaktoris, laadida tabel faili, näidata praegust ülesannete tabelit ja kustutada ülesannete tabel. Näiteid crontab utiliidi kasutamisest:

crontab -e # redigeeri ülesannete tabelit
crontab -l # näita ülesannete tabelit
crontab -r # kustuta ülesannete tabel
crontab path/to/file.crontab # laadi tabel failist

Päringu tegemisel, mis sisaldab teavet protokollide kohta, näeme järgmist: crontab -e kasutatakse redaktorit, mis on määratud tavalises keskkonnamuutujas EDITOR.

Ülesanded ise on kirjeldatud järgmises formaadis:

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

Esimesed viis väljade kirjet: minutid [1..60], tunnid [0..23], kuu päevad [1..31], kuud [1..12], nädalapäevad [0..6], kus 0 on pühapäev. Viimane, kuues väli – string, mis täidetakse tavalise käsutõlgi poolt.

Esimeses viies väljas saab väärtusi loetleda koma kaudu:

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

Või kriipsu kaudu:

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

Kasutajate juurdepääsu ülesannete planeerimisele reguleerivad POSIX failid cron.allow ja cron.deny, kus on loetletud vastavalt, kasutajad, kellel on juurdepääs crontab'ile, ja kasutajad, kellel ei ole programmi juurdepääsu. Nende failide asukohta ei reguleeri standard kuidagi.

Käivitatavatele programmidele tuleb vähemalt neli keskkonnamuutujat edastada:

  1. HOME — kasutaja kodudirectory.
  2. LOGNAME — kasutaja sisselogimisenimi.
  3. PATH — tee, mille kaudu leida süsteemi standardseid utiliite.
  4. SHELL — tee kasutatud käsutõlgi juurde.

Oluline on märkida, et POSIX ei ütle midagi selle kohta, kust need muutujate väärtused tulevad.

Müügi hitt — Vixie cron 3.0pl1

Tuntuimate cron varianti ühine esivanem on Vixie cron 3.0pl1, mille esitles 1992. aastal comp.sources.unix'isse. Selle versiooni peamised omadused vaatamegi lähemalt.

Vixie cron koosneb kahest programmist (cron ja crontab). Nagu tavaliselt, demon vastutab süsteemi ülesannete tabelist lugemise ja käivitamise eest ning kasutaja ülesande tabelite muutmise eest vastutab utiliit crontab.

Ülesande tabel ja konfiguratsioonifailid

Superkasutaja ülesande tabel asub failis /etc/crontab. Süsteemi tabeli süntaks vastab Vixie cron'i süntaksile, arvestades, et kuues veerg näitab kasutajanime, kelle nime alt ülesanne käivitatakse:

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

Tavaliste kasutajate ülesande tabelid asuvad failides /var/cron/tabs/username ja kasutavad tavalist süntaksit. Kui crontab'i utiliiti käitatakse kasutaja nimel, muudetakse just neid faile.

Kasutaja juurdepääsude loendid crontab'ile on hallatud failides /var/cron/allow ja /var/cron/deny, kuhu piisab kasutajanime kirjutamisest eraldi reale.

Täiendav süntaks

Võrreldes POSIX crontab'iga sisaldab Paul Vixie lahendus mitmeid väga kasulikke muudatusi utiliidi ülesande tabeli süntaksis.

Saab on saadaval uus tabelite süntaks: näiteks saab näidata nädalapäevi või kuulisi nimepidi (Mon, Tue jne):

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

Saab määrata sammu, mille järel ülesandeid käivitatakse:

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

Sammud ja intervallid võib omavahel kombineerida:

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

Toetatakse intuitiivseid alternatiive tavalisele süntaksile (reboot, yearly, annually, monthly, weekly, daily, midnight, hourly):

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

Ülesannete käitamise keskkond

Vixie cron võimaldab muuta käivitatavate rakenduste keskkonda.

Keskkonnamuutujad USER, LOGNAME ja HOME ei ole lihtsalt deemoniga antud, vaid need võetakse failist passwd. Muutuja PATH saab väärtuse "/usr/bin:/bin", ning SHELL väärtuse "/bin/sh". Kõikide muutujate väärtusi, välja arvatud LOGNAME, saab muuta kasutaja tabelites.

Mõningaid keskkonnamuutujaid (eelkõige SHELL ja HOME) kasutab cron ülesande käivitamiseks. Nii võib näha, kuidas bashit kasutatakse tavalise sh asemel kasutajaülesannete käivitamiseks:

SHELL=/bin/bash
HOME=/tmp/
# exec käivitatakse bashis tmp-s
* * * * * /path/to/exec

Lõppkokkuvõttes edastatakse kõik tabelis määratud keskkonnamuutujad (mida cron kasutab või mis on protsessile vajalikud) käivitatud ülesandele.

Crontabi faili redigeerimiseks kasutatakse redigeerijat, mis on määratud keskkonnamuutus VISUAL või EDITOR. Kui crontabi käivitanud keskkonnas ei ole need muutujad määratud, kasutatakse "/usr/ucb/vi" (ucb viitab tõenäoliselt California ülikoolile, Berkeley).

cron Debianis ja Ubuntu's

Debiani ja selle tuletatud distributsioonide arendajad on välja andnud oluliselt muudetud versiooni Vixie cron 3.0pl1. Failide tabelite süntaksis pole muudatusi, kasutajatele on see sama Vixie cron. Suurimad uued omadused: tugi syslog, SELinux ja PAM.

Vähem silmatorkavad, kuid tajutavad muudatused on seadistamisfailide ja ülesande tabelite asukohad.

Kasutaja tabelid Debiani süsteemis asuvad kataloogis /var/spool/cron/crontabs, süsteemitabel jääb endiselt /etc/crontab. Spetsiifilised Debiani pakettide ülesande tabelid asuvad /etc/cron.d, kust cron-deemon need automaatselt lugeda saab. Kasutajate juurdepääsu haldamine toimub failide /etc/cron.allow ja /etc/cron.deny kaudu.

Vaikimisi käsurida on endiselt /bin/sh, mille rollis Debiani süsteemis on väike POSIX-ühilduv shell dash, mis käivitatakse ilma ühegi seadistuse lugemiseta (mitteinteraktiivses režiimis).

Viimase Debian versiooniga käivitub cron läbi systemd, ning käivitamise konfiguratsiooni saab vaadata failist /lib/systemd/system/cron.service. Teenuse konfiguratsioonis ei ole midagi erilist, ning peene kontrolli ülesannete üle saab teostada keskkonnamuutujate kaudu, mis on määratud iga kasutaja crontab'is.

cronie RedHat, Fedora ja CentOS-is

cronie — Vixie croni 4.1 haru. Nagu Debiani puhul, ei ole süntaks muutunud, kuid on lisatud PAM ja SELinux-i tugi, klastrite tugi, failide jälgimine inotify abil ning muid võimalusi.

Vaikekonfiguratsioon asub tavapärastes kohtades: süsteemilaud — /etc/crontab, paketid paigutavad oma tabelid /etc/cron.d, kasutajate tabelid aga /var/spool/cron/crontabs.

Demon käivitub systemd halduses, teenuse konfiguratsioon asub /lib/systemd/system/crond.service.

Red Hat'i taolistes jaotustes kasutatakse vaikimisi käivitamisel /bin/sh, milleks on standardne bash. Tuleb märkida, et cron'te ülesannete käivitamisel läbi /bin/sh käivitatakse bash käsurea tõlgendus POSIX-ühilduvas režiimis ning ta ei loe mingeid täiendavaid konfigureerimisi, töötades mitteinteraktiivses režiimis.

cronie SLES'is ja openSUSE's

Saksa jaotus SLES ja selle derivative openSUSE kasutavad sama cronie. Demon käivitatakse samuti systemd halduses, teenuse konfiguratsioon asub /usr/lib/systemd/system/cron.service. Konfiguratsioon: /etc/crontab, /etc/cron.d, /var/spool/cron/tabs. /bin/sh on sama bash, käivitatud POSIX-ühilduvas mitteinteraktiivses režiimis.

Vixie cron'i ülesehitus

Kaasaegsed cron'i potentsiaalid ei ole võrreldes Vixie cron'iga radikaalselt muutunud, kuid siiski on nad omandanud uusi võimalusi, mis ei ole vajalikud programmi töö mõistmiseks. Paljud neist laiendustest on halvasti vormistatud ja segavad koodi. Originaalkood cron'ile Paul Vixie's õiguses on tõeliselt nauditav lugeda.

Seetõttu otsustasin cron'i ülesehitust analüüsida Vixie cron 3.0pl1 näitel, mis on ühine mõlemale cron'i programmi arenduse harule. Ma lihtsustan näiteid, eemaldades lugemist segavad ifdef'id ja jättes tähelepanuta kõrvalised detailid.

Demoni töö saab jagada mitmeks etapiks:

  1. Programmi alustamine.
  2. Ülesannete käivitamiseks vajaliku nimekirja kogumine ja uuendamine.
  3. Cron'i peamise tsükli töö.
  4. Ülesande käivitamine.

Analüüsime neid järjestikku.

Algatamine

Käivitamisel kontrollimise pärast krondiprotsess seab SIGCHLD ja SIGHUP signaalide käitlejad. Esimene logib teate, et alamprotsess on lõpetanud, teine - sulgeb logifaili failikirje.

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

Kriitiline demon on süsteemis alati ühekordne, ainult superkasutajana ja krondemoni peadirigeerimisest. Järgmised kutsed loovad demonprotsessi PID-failiga, veenduvad, et kasutaja on õige ja muudavad praeguse direktoriumi peadirigeerimiseks:

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

Seatakse vaikimisi tee, mida kasutatakse protsesside käivitamisel:

setenv("PATH", _PATH_DEFPATH, 1);

Seejärel protsess "demoniseeritakse": luuakse alamprotsessi koopiad fork'i väljakutsega ja uus sessioon alamprotsessis (setsid kutsumine). Vanema protsessi jaoks pole enam vajadust - ja see lõpetab töö:

switch (fork()) {
case -1:
    /* kriitiline viga ja lõpetamine */
    exit(0);
break;
case 0:
    /* alamprotsess */
    (void) setsid();
break;
default:
    /* vanemprotsess lõpetab töö */
    _exit(0);
}

Vanemprotsessi lõpetamine vabastab lukku faililukus. Lisaks on vajalik PID uuendada alumise protsessi jaoks. Pärast seda täidetakse ülesannete andmebaas:

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

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

Seejärel läheb cron peatsesse töötsüklisse. Kuid enne, kui tasub vaadata ülesannete loendi koormust.

Ülesannete loendi kogumine ja uuendamine

Ülesannete loendi laadimise eest vastutab funktsioon load_database. See kontrollib peamist süsteemi crontab'i ja kasutajate failide kausta. Kui failid ja kataloog ei ole muutunud, siis ülesannete loendit ei loeta uuesti. Vastupidisel juhul hakkab uut ülesannete loendit koostama.

Süsteemifaili laadimine erifailide nimede ja tabelitega:

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

Kasutajatabelite laadimine tsüklis:

while (NULL != (dp = readdir(dir))) {
    char    fname[MAXNAMLEN+1],
            tabname[MAXNAMLEN+1];
    /* lugeda faile, kus on punkt, pole vaja */
    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);
}

Pärast seda asendatakse vana andmebaas uuega.

Ülaltoodud näidetes tagab funktsiooni process_crontab väljakutse, et kasutaja, kes vastab tabeli nime failile (kui see pole superkasutaja), eksisteerib pärast seda kutsub load_user. Viimane loeb faili juba reale:

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

Siin kas seotakse keskkonnamuutujaid (näiteks VAR=vaba) funktsioonide load_env / env_set kaudu või loetakse ülesande kirjeldust (** * * * /path/to/exec) funktsiooni load_entry kaudu.

Load_entry'ist tagastatav entry-kontseptsioon on meie ülesanne, mis pannakse ühte asjade nimekirja. Funktsioonis toimub pikaldane ajavormi analüüs, meid huvitab rohkem keskkonnamuutujate ja ülesande käivitamisparameetrite koostamine:

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

Praeguste ülesannete loendiga töötab põhitsükkel.

Peamine tsükkel

Algne cron Version 7 Unixi all töötas väga lihtsalt: see luges konfiguratsiooni tsüklis, käivitas superkasutaja praeguse minuti ülesandeid ja magas kuni järgmise minuti alguseni. See lihtne lähenemine nõudis vanadel masinatel liiga palju ressursse.

SysV-s pakuti alternatiivset versiooni, kus demon magas kas hetkelise minuti või 30 minuti järgi. Sellises režiimis kulus ressursse konfiguratsiooni ülelugemise ja ülesannete kontrollimise jaoks vähem, kuid ülesannete loendi kiireks värskendamiseks muutus see ebamugavaks.

Vixie cron naasis ülesannete loendite kontrollimise juurde minuti kaupa, õnneks olid 80-ndate lõpuks tavalised Unix-masinad ressursse palju rohkem:

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

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

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

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

Küsimuste täitmise eest vastutab funktsioon cron_sleep, mis kutsub üles funktsioone job_runqueue (ülesannete läbivaatamine ja käivitamine) ja do_command (iga eraldi ülesande käivitamine). Viimat mainitud funktsiooni tasub arutada lähemalt.

Ülesande käivitamine

Funktsioon do_command on kirjutatud heas Unix-stiilis, st asünkroonse ülesande täitmiseks teeb ta fork. Vanemprotsess jätkab ülesannete käivitamist, lapseprotsess tegeleb ülesande protsessi ettevalmistamisega:

switch (fork()) {
case -1:
    /* ei suutnud fork'i teostada */
    break;
case 0:
    /* lapsprotsess: juhuks, kui proovime uuesti haarata peamist lukku */
    acquire_daemonlock(1);
    /* liigume ülesande protsessi moodustamise juurde */
    child_process(e, u);
    /* pärast lõpetamist lõpetab lapsprotsess oma töö */
    _exit(OK_EXIT);
    break;
default:
    /* vanemprotsess jätkab tööd */
    break;
}

Child_processs on palju loogikat: see võtab enda peale standaardseid väljundeid ja vigu, et edastada need e-postile (kui ülesannete tabelis on määratud keskkonnamuutuja MAILTO), ja lõpuks ootab see põhiprotsessi lõpetamist.

Ülesande protsess moodustatakse veel ühe fork'iga:

switch (vfork()) {
case -1:
    /* vea korral lõpetab see kohe töö */
    exit(ERROR_EXIT);
case 0:
    /* lapsprotsess loob uue sessiooni, terminali jne.
     */
    (void) setsid();

    /*
     * seejärel on kaugeleulatuv konfigureerimine, jätame lühiduse huvides vahele
     */

    /* kaustavahetus, kasutaja ja grupi kasutaja vahetus,
     * st protsess ei ole enam superkasutaja
     */
    setgid(e->gid);
    setuid(e->uid);
    chdir(env_get("HOME", e->envp));

    /* käsu käivitamine
     */
    {
        /* keskkonnamuutuja SHELL näitab tõlgendajat, mida käivitada */
        char *shell = env_get("SHELL", e->envp);

        /* protsess käivitatakse ilma vanemprotsessi keskkonna edastamata,
         * st just nii, nagu on ülesannete tabelis kirjeldatud */
        execle(shell, shell, "-c", e->cmd, (char *)0, e->envp);

        /* viga — ja protsess ei käivitunud? töö lõpetamine */
        perror("execl");
        _exit(ERROR_EXIT);
    }
    break;
default:
    /* ise protsess jätkab tööd: ootab lõpetamist ja väljundit */
    break;
}

See on põhimõtteliselt kogu cron. Mõned huvitavad detailid, näiteks kaugsüsteemi kasutajate arvestamine, olen vahele jätnud, kuid peamine on välja toodud.

Eessõna

Cron on üllatavalt lihtne ja kasulik programm, mis on loodud parimad traditsioonid järgides Unix’i maailmas. See ei tee midagi üleliigset, kuid oma tööd teeb see juba mitu aastakümmet suurepäraselt. Ubuntu versiooni koodi tutvumine ei olnud rohkem kui tunni asi ja ma nautisin seda tohutult! Loodan, et suudasin seda teiega jagada.

Ma ei tea, kuidas teie, aga mulle on veidi kurb mõelda, et moodsal programmeerimisel, millel on kalduvus ülekompleksitusele ja üleabstraktsioonile, ei ole juba ammu sarnast lihtsust.

On olemas palju kaasaegseid cron'i alternatiive: systemd-timers võimaldavad korraldada keerulisi süsteeme sõltuvustega, fcron'iga saab ülesannete ressursikasutust paindlikumalt reguleerida. Aga isiklikult on mul alati piisanud kõige lihtsamatest crontabidest.

Kokkuvõttes, armastage Unix'i, kasutage lihtsaid programme ja ärge unustage lugeda manuaale oma platvormi jaoks!

Allikas: habr.com

Osta usaldusväärne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster