Cron in Linux: geschiedenis, gebruik en apparaat

Cron in Linux: geschiedenis, gebruik en apparaat

De klassieker schreef dat happy hours niet kijken. In die wilde tijden waren er noch programmeurs, noch Unix, maar tegenwoordig weten programmeurs het zeker: cron zal de tijd bijhouden in plaats van hen.

Hulpprogramma's voor de opdrachtregel zijn zowel een zwakte als een hele klus voor mij. sed, awk, wc, cut en andere oude programma's worden elke dag door scripts op onze servers uitgevoerd. Velen van hen zijn ontworpen als taken voor cron, een planner die oorspronkelijk uit de jaren 70 stamt.

Lange tijd heb ik cron oppervlakkig gebruikt, zonder in details te treden, maar op een dag, toen ik een fout tegenkwam bij het uitvoeren van een script, besloot ik er grondig naar te kijken. Dit is hoe dit artikel verscheen. Tijdens het schrijven raakte ik bekend met POSIX crontab, de belangrijkste cron-opties in populaire Linux-distributies en de structuur van sommige daarvan.

Gebruik je Linux en voer je cron-taken uit? Ben je geïnteresseerd in systeemapplicatiearchitectuur in Unix? Dan zijn we onderweg!

Inhoud

Oorsprong der soorten

Het periodiek uitvoeren van gebruikers- of systeemprogramma's is een duidelijke noodzaak in alle besturingssystemen. Daarom realiseerden programmeurs zich al lang geleden de behoefte aan diensten waarmee ze taken centraal konden plannen en uitvoeren.

Unix-achtige besturingssystemen vinden hun oorsprong in versie 7 Unix, ontwikkeld in de jaren '70 van de vorige eeuw bij Bell Labs, onder meer door de beroemde Ken Thompson. Versie 7 Unix bevatte ook cron, een service voor het regelmatig uitvoeren van superuser-taken.

Een typische moderne cron is een eenvoudig programma, maar het bedieningsalgoritme van de originele versie was nog eenvoudiger: de service werd één keer per minuut wakker, las een tabel met taken uit een enkel bestand (/etc/lib/crontab) en voerde deze uit voor de superuser de taken die op dit moment hadden moeten worden uitgevoerd.

Vervolgens werden verbeterde versies van de eenvoudige en nuttige service geleverd bij alle Unix-achtige besturingssystemen.

Algemene beschrijvingen van het crontab-formaat en de basisprincipes van de werking van het hulpprogramma werden in 1992 opgenomen in de belangrijkste standaard van Unix-achtige besturingssystemen - POSIX -, en zo werd cron van een de facto standaard een de jure standaard.

In 1987 bracht Paul Vixie, nadat hij Unix-gebruikers had ondervraagd over hun wensen voor cron, een andere versie van de daemon uit die enkele van de problemen van de traditionele cron corrigeerde en de syntaxis van tabelbestanden uitbreidde.

Tegen de derde versie van Vixie begon cron aan de POSIX-vereisten te voldoen, bovendien had het programma een liberale licentie, of beter gezegd, er was helemaal geen licentie, behalve de wensen in de README: de auteur geeft geen garanties, de naam van de auteur kan niet worden verwijderd en het programma kan alleen samen met de broncode worden verkocht. Deze vereisten bleken verenigbaar te zijn met de principes van vrije software die in die jaren aan populariteit wonnen, dus sommige van de belangrijkste Linux-distributies die begin jaren negentig verschenen, gebruikten Vixie cron als hun systeem en zijn deze nog steeds aan het ontwikkelen.

In het bijzonder ontwikkelen Red Hat en SUSE een fork van Vixie cron - cronie, en Debian en Ubuntu gebruiken de originele editie van Vixie cron met veel patches.

Laten we eerst kennis maken met het gebruikershulpprogramma crontab beschreven in POSIX, waarna we zullen kijken naar de syntaxisextensies in Vixie cron en het gebruik van variaties van Vixie cron in populaire Linux-distributies. En tot slot is de kers op de taart de analyse van het cron daemon-apparaat.

POSIX crontab

Als de originele cron altijd voor de superuser werkte, behandelen moderne planners vaak taken van gewone gebruikers, wat veiliger en handiger is.

Crons worden geleverd als een set van twee programma's: de constant actieve cron daemon en het crontab-hulpprogramma dat beschikbaar is voor gebruikers. Met dit laatste kunt u taaktabellen bewerken die specifiek zijn voor elke gebruiker in het systeem, terwijl de daemon taken start vanuit gebruikers- en systeemtabellen.

В POSIX-standaard het gedrag van de daemon wordt op geen enkele manier beschreven en alleen het gebruikersprogramma is geformaliseerd crontab. Het bestaan ​​van mechanismen voor het starten van gebruikerstaken is uiteraard impliciet, maar wordt niet in detail beschreven.

Door het crontab-hulpprogramma aan te roepen, kunt u vier dingen doen: de takentabel van de gebruiker in de editor bewerken, de tabel uit een bestand laden, de huidige taaktabel weergeven en de taaktabel leegmaken. Voorbeelden van hoe het crontab-hulpprogramma werkt:

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

Wanneer gebeld crontab -e de editor die is opgegeven in de standaard omgevingsvariabele zal worden gebruikt EDITOR.

De taken zelf worden beschreven in het volgende formaat:

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

De eerste vijf velden van de records: minuten [1..60], uren [0..23], dagen van de maand [1..31], maanden [1..12], dagen van de week [0. .6], waarbij 0 zondag is. Het laatste, zesde veld is een regel die zal worden uitgevoerd door de standaard commando-interpreter.

In de eerste vijf velden kunnen waarden worden weergegeven, gescheiden door komma's:

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

Of met een koppelteken:

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

Gebruikerstoegang tot taakplanning wordt in POSIX geregeld door de bestanden cron.allow en cron.deny, waarin respectievelijk gebruikers met toegang tot crontab en gebruikers zonder toegang tot het programma worden vermeld. De standaard regelt op geen enkele wijze de locatie van deze bestanden.

Volgens de standaard moeten ten minste vier omgevingsvariabelen worden doorgegeven aan gelanceerde programma's:

  1. HOME - de thuismap van de gebruiker.
  2. LOGNAME — gebruikersaanmelding.
  3. PATH is het pad waar u standaard systeemhulpprogramma's kunt vinden.
  4. SHELL — pad naar de gebruikte opdrachtinterpreter.

Opvallend is dat POSIX niets zegt over waar de waarden voor deze variabelen vandaan komen.

Bestseller - Vixie cron 3.0pl1

De gemeenschappelijke voorouder van populaire cron-varianten is Vixie cron 3.0pl1, geïntroduceerd in de comp.sources.unix mailinglijst in 1992. We zullen de belangrijkste kenmerken van deze versie in meer detail bekijken.

Vixie cron wordt geleverd in twee programma's (cron en crontab). Zoals gebruikelijk is de daemon verantwoordelijk voor het lezen en uitvoeren van taken uit de systeemtakentabel en de taaktabellen van individuele gebruikers, en is het crontab-hulpprogramma verantwoordelijk voor het bewerken van gebruikerstabellen.

Taaktabel en configuratiebestanden

De superuser-taaktabel bevindt zich in /etc/crontab. De syntaxis van de systeemtabel komt overeen met de syntaxis van Vixie cron, met de uitzondering dat de zesde kolom daarin de naam aangeeft van de gebruiker namens wie de taak wordt gestart:

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

Normale gebruikerstaaktabellen bevinden zich in /var/cron/tabs/username en gebruiken dezelfde syntaxis. Wanneer u het crontab-hulpprogramma als gebruiker uitvoert, zijn dit de bestanden die worden bewerkt.

De lijsten met gebruikers met toegang tot crontab worden beheerd in de bestanden /var/cron/allow en /var/cron/deny, waar u alleen de gebruikersnaam op een aparte regel hoeft in te voeren.

Uitgebreide syntaxis

Vergeleken met POSIX crontab bevat de oplossing van Paul Vixey verschillende zeer nuttige wijzigingen in de syntaxis van de taaktabellen van het hulpprogramma.

Er is een nieuwe tabelsyntaxis beschikbaar gekomen: u kunt bijvoorbeeld dagen van de week of maanden op naam opgeven (ma, di, enzovoort):

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

U kunt de stap opgeven waarmee taken worden gestart:

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

Stappen en intervallen kunnen worden gemengd:

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

Er worden intuïtieve alternatieven voor de gebruikelijke syntaxis ondersteund (opnieuw opstarten, jaarlijks, jaarlijks, maandelijks, wekelijks, dagelijks, middernacht, elk uur):

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

Omgeving voor taakuitvoering

Met Vixie cron kunt u de omgeving van actieve applicaties wijzigen.

De omgevingsvariabelen USER, LOGNAME en HOME worden niet simpelweg door de daemon aangeleverd, maar worden uit een bestand gehaald passwd. De PATH-variabele is ingesteld op "/usr/bin:/bin" en de SHELL-variabele is ingesteld op "/bin/sh". De waarden van alle variabelen behalve LOGNAME kunnen in gebruikerstabellen worden gewijzigd.

Sommige omgevingsvariabelen (met name SHELL en HOME) worden door cron zelf gebruikt om de taak uit te voeren. Hier ziet u hoe het gebruik van bash in plaats van standaard sh om aangepaste taken uit te voeren eruit zou kunnen zien:

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

Uiteindelijk zullen alle omgevingsvariabelen die in de tabel zijn gedefinieerd (gebruikt door cron of nodig voor het proces) worden doorgegeven aan de actieve taak.

Om bestanden te bewerken gebruikt crontab de editor die is opgegeven in de omgevingsvariabele VISUAL of EDITOR. Als in de omgeving waarin crontab werd uitgevoerd deze variabelen niet zijn gedefinieerd, wordt "/usr/ucb/vi" gebruikt (ucb is waarschijnlijk de University of California, Berkeley).

cron op Debian en Ubuntu

De ontwikkelaars van Debian en afgeleide distributies hebben dit vrijgegeven sterk gewijzigde versie Vixie cron-versie 3.0pl1. Er zijn geen verschillen in de syntaxis van tabelbestanden; voor gebruikers is het dezelfde Vixie-cron. Grootste nieuwe functie: ondersteuning syslog, SELinux и PAM.

Minder opvallende, maar tastbare veranderingen zijn onder meer de locatie van configuratiebestanden en taaktabellen.

Gebruikerstabellen in Debian bevinden zich in de map /var/spool/cron/crontabs, de systeemtabel is daar nog steeds - in /etc/crontab. De pakketspecifieke taaktabellen van Debian worden in /etc/cron.d geplaatst, van waaruit de cron-daemon ze automatisch leest. De toegangscontrole voor gebruikers wordt beheerd door de bestanden /etc/cron.allow en /etc/cron.deny.

De standaardshell is nog steeds /bin/sh, wat in Debian een kleine POSIX-compatibele shell is scheutje, gelanceerd zonder enige configuratie te lezen (in niet-interactieve modus).

Cron zelf wordt in de nieuwste versies van Debian gestart via systemd, en de opstartconfiguratie kan worden bekeken in /lib/systemd/system/cron.service. Er is niets bijzonders aan de serviceconfiguratie; subtieler taakbeheer kan worden gedaan via omgevingsvariabelen die rechtstreeks in de crontab van elke gebruiker worden gedeclareerd.

maatje op RedHat, Fedora en CentOS

Cronie — fork van Vixie cron versie 4.1. Net als in Debian is de syntaxis niet veranderd, maar is ondersteuning voor PAM en SELinux, het werken in een cluster, het volgen van bestanden met behulp van inotify en andere functies toegevoegd.

De standaardconfiguratie bevindt zich op de gebruikelijke plaatsen: de systeemtabel bevindt zich in /etc/crontab, pakketten plaatsen hun tabellen in /etc/cron.d, gebruikerstabellen gaan in /var/spool/cron/crontabs.

De daemon draait onder systemd-controle, de serviceconfiguratie is /lib/systemd/system/crond.service.

Op Red Hat-achtige distributies wordt /bin/sh standaard gebruikt bij het opstarten, wat de standaard bash is. Opgemerkt moet worden dat bij het uitvoeren van cron-taken via /bin/sh, de bash-shell start in POSIX-compatibele modus en geen aanvullende configuratie leest, omdat deze in niet-interactieve modus draait.

maatje in SLES en openSUSE

De Duitse distributie SLES en zijn afgeleide openSUSE gebruiken dezelfde trawanten. De daemon wordt hier ook gestart onder systemd, de serviceconfiguratie bevindt zich in /usr/lib/systemd/system/cron.service. Configuratie: /etc/crontab, /etc/cron.d, /var/spool/cron/tabs. /bin/sh is dezelfde bash die draait in POSIX-compatibele niet-interactieve modus.

Vixie cron-apparaat

Moderne afstammelingen van cron zijn niet radicaal veranderd vergeleken met Vixie cron, maar hebben toch nieuwe functies verworven die niet nodig zijn om de principes van het programma te begrijpen. Veel van deze extensies zijn slecht ontworpen en verwarren de code. De originele cron-broncode van Paul Vixey is een genot om te lezen.

Daarom besloot ik het cron-apparaat te analyseren met behulp van het voorbeeld van een cron-programma dat beide ontwikkelingstakken gemeen hebben: Vixie cron 3.0pl1. Ik zal de voorbeelden vereenvoudigen door ifdefs te verwijderen die het lezen bemoeilijken en door kleine details weg te laten.

Het werk van de demon kan in verschillende fasen worden verdeeld:

  1. Initialiseren van het programma.
  2. Het verzamelen en bijwerken van de lijst met uit te voeren taken.
  3. Belangrijkste cron-lus actief.
  4. Begin een taak.

Laten we ze in volgorde bekijken.

Initialisatie

Wanneer cron is gestart, installeert cron, na het controleren van de procesargumenten, de signaalbehandelaars SIGCHLD en SIGHUP. De eerste maakt een logboekinvoer over de beëindiging van het onderliggende proces, de tweede sluit de bestandsdescriptor van het logbestand:

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

De cron-daemon draait altijd alleen op het systeem, alleen als superuser en vanuit de hoofdcron-directory. De volgende oproepen creëren een lock-bestand met de PID van het daemon-proces, zorgen ervoor dat de gebruiker correct is en veranderen de huidige map naar de hoofdmap:

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

Het standaardpad is ingesteld, dat zal worden gebruikt bij het starten van processen:

setenv("PATH", _PATH_DEFPATH, 1);

Vervolgens wordt het proces “gedaemoniseerd”: het creëert een onderliggende kopie van het proces door fork aan te roepen en een nieuwe sessie in het onderliggende proces (aanroepen van setid). Het bovenliggende proces is niet langer nodig en wordt afgesloten:

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

Door het beëindigen van het bovenliggende proces wordt de vergrendeling van het vergrendelingsbestand opgeheven. Bovendien is het vereist om de PID in het bestand bij te werken voor het kind. Hierna wordt de takendatabase ingevuld:

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

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

Vervolgens gaat cron verder met de hoofdwerkcyclus. Maar daarvoor is het de moeite waard om eens te kijken naar het laden van de takenlijst.

Het verzamelen en bijwerken van de takenlijst

De functie load_database is verantwoordelijk voor het laden van de lijst met taken. Het controleert de crontab van het hoofdsysteem en de directory met gebruikersbestanden. Als de bestanden en directory niet zijn gewijzigd, wordt de takenlijst niet opnieuw gelezen. Anders begint zich een nieuwe lijst met taken te vormen.

Een systeembestand laden met speciale bestands- en tabelnamen:

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

Gebruikerstabellen in een lus laden:

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

Daarna wordt de oude database vervangen door een nieuwe.

In de bovenstaande voorbeelden verifieert de functieaanroep process_crontab dat er een gebruiker bestaat die overeenkomt met de tabelbestandsnaam (tenzij deze een superuser is) en roept vervolgens load_user aan. Deze laatste leest het bestand zelf al regel voor regel:

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

Hier wordt óf de omgevingsvariabele ingesteld (regels van de vorm VAR=waarde) met behulp van de functies load_env / env_set, óf de taakbeschrijving wordt gelezen (* * * * * /path/to/exec) met behulp van de functie load_entry.

De entry-entiteit die load_entry retourneert is onze taak, die in de algemene lijst met taken wordt geplaatst. De functie zelf voert een uitgebreide analyse van het tijdformaat uit, maar we zijn meer geïnteresseerd in de vorming van omgevingsvariabelen en parameters voor het starten van taken:

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

De hoofdlus werkt met de huidige lijst met taken.

Hoofdlus

De originele cron van versie 7 Unix werkte heel eenvoudig: hij las de configuratie in een lus opnieuw, lanceerde de taken van de huidige minuut als superuser en sliep tot het begin van de volgende minuut. Deze eenvoudige aanpak op oudere machines vereiste te veel bronnen.

Er werd een alternatieve versie voorgesteld in SysV, waarin de daemon ging slapen tot de dichtstbijzijnde minuut waarvoor de taak was gedefinieerd, of gedurende 30 minuten. Er werden in deze modus minder bronnen verbruikt voor het opnieuw lezen van de configuratie en het controleren van taken, maar het snel bijwerken van de lijst met taken werd lastig.

Vixie cron keerde terug naar het één keer per minuut controleren van takenlijsten, gelukkig waren er tegen het einde van de jaren 80 aanzienlijk meer bronnen op standaard Unix-machines:

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

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

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

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

De cron_sleep-functie is rechtstreeks betrokken bij het uitvoeren van taken, waarbij de functies job_runqueue (taken opsommen en uitvoeren) en do_command (elke afzonderlijke taak worden uitgevoerd) worden aangeroepen. De laatste functie is de moeite waard om nader te onderzoeken.

Een taak uitvoeren

De do_command-functie wordt uitgevoerd in goede Unix-stijl, dat wil zeggen dat er een fork wordt uitgevoerd om de taak asynchroon uit te voeren. Het bovenliggende proces gaat door met het starten van taken, het onderliggende proces bereidt het taakproces voor:

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

Er zit behoorlijk wat logica in child_process: het neemt standaarduitvoer- en foutstromen over naar zichzelf, om het vervolgens naar mail te sturen (als de omgevingsvariabele MAILTO is gespecificeerd in de taaktabel), en wacht ten slotte op de belangrijkste proces van de taak die moet worden voltooid.

Het taakproces wordt gevormd door een andere vork:

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

Dat is eigenlijk alles wat cron is. Ik heb een aantal interessante details weggelaten, bijvoorbeeld de boekhouding voor externe gebruikers, maar ik heb het belangrijkste uiteengezet.

nawoord

Cron is een verrassend eenvoudig en nuttig programma, gemaakt in de beste tradities van de Unix-wereld. Ze doet niets extra’s, maar doet haar werk al tientallen jaren uitstekend. Het doornemen van de code voor de versie die bij Ubuntu wordt geleverd duurde niet meer dan een uur, en ik had veel plezier! Ik hoop dat ik het met jullie heb kunnen delen.

Ik weet niet hoe het met jou zit, maar ik ben een beetje verdrietig om te beseffen dat moderne programmering, met zijn neiging om te ingewikkeld en te abstract te zijn, al lange tijd niet bevorderlijk is geweest voor een dergelijke eenvoud.

Er zijn veel moderne alternatieven voor cron: met systemd-timers kunt u complexe systemen met afhankelijkheden organiseren, met fcron kunt u het resourceverbruik flexibeler per taak regelen. Maar persoonlijk was de eenvoudigste crontab voor mij altijd voldoende.

Kortom, houd van Unix, gebruik eenvoudige programma's en vergeet niet de mana voor jouw platform te lezen!

Bron: www.habr.com

Voeg een reactie