Plak hem in en krijg de volgende 8 runmomenten, in je eigen tijdzone, plus de valkuilen die je niet ziet door de string even vluchtig te lezen.
Hij ontleedt de expressie zoals Vixie/POSIX-cron dat doet — 5 velden, of 6 met een secondenveld vooraan — en werkt uit wat er staat: welke waarde in welk veld hoort, en de volgende 8 momenten waarop hij daadwerkelijk zou vuren, berekend in kloktijd voor de tijdzone die je kiest. Niets van wat je plakt gaat ergens heen; zowel het ontleden als het rekenen met datums gebeurt in je browser.
Hij bestaat omdat een cron-string met opzet compact is, en compact is niet
hetzelfde als leesbaar. 30 2 * * 1-5 is volstrekt eenduidig voor het programma
dat hem uitvoert, en oprecht lastig te ontcijferen om elf uur 's avonds, als je
probeert te achterhalen waarom een job afgelopen dinsdag wel of niet is gelopen.
Standaardcron leest van links naar rechts als minuut, uur, dag van de maand,
maand, dag van de week. Sommige schedulers — deze tool incluis — accepteren
een optioneel veld seconden vooraan, wat er zes in totaal maakt. Elk veld
neemt een getal, een lijst gescheiden door komma's, een bereik (1-5), een stap
(*/15) of een combinatie (10-50/10). De velden maand en dag van de week
accepteren ook namen: JAN-DEC en SUN-SAT (of 0-7, waarbij zowel 0
als 7 zondag betekent).
* betekent "elke waarde" voor dat veld — * * * * * vuurt elke minuut.
*/15 betekent "elke 15e waarde vanaf het minimum van het veld" — voor minuten
is dat :00, :15, :30, :45.
Gewone cron — die in je crontab — heeft 5 velden, met één run per minuut als
ondergrens. Sommige tools (deze, en bijvoorbeeld node-cron) accepteren een zesde
veld vooraan voor seconden, wat de enige manier is om "elke 10 seconden"
überhaupt in cron-syntaxis uit te drukken. De twee zijn makkelijk te verwarren:
0 30 2 * * * lijkt 2.30 uur te betekenen, maar met zes velden is de eerste 0
het secondenveld en vuurt het schema in werkelijkheid om 02:30:00 — wat als
cron met 5 velden 30 2 * * * zou zijn. Velden verkeerd tellen is verreweg de
meest voorkomende manier om de juiste job op het verkeerde tijdstip in te
plannen.
De @-afkortingen — @hourly, @daily, @weekly, @monthly, @yearly
(@annually en @midnight zijn aliassen) — klappen uit naar vaste
standaardcron-expressies en gedragen zich identiek. @reboot is een ander
verhaal; zie hieronder.
0 0 13 * 5 leest als "de 13e, als het een vrijdag is" — vrijdag de 13e. Dat is
het niet. Standaardcron behandelt dag van de maand en dag van de week als een
OF zodra beide beperkt zijn: de job vuurt op de 13e van elke maand en op
elke vrijdag, wat voor de meeste maanden vijf of zes runs oplevert in plaats van
de ene die je voor ogen had.
Dit bijt alleen als beide velden tegelijk beperkt zijn. 0 0 13 * * (elke 13e,
dag van de week op * gelaten) betekent precies wat het lijkt te betekenen, en
0 0 * * 5 (elke vrijdag) ook. Het is de combinatie die stilletjes omschakelt
van EN naar OF, en het is een van de oudste verrassingen in cron — POSIX schrijft
het zo voor, elke serieuze cron-implementatie volgt het, en het overvalt nog
altijd mensen die leerden programmeren nadat de meeste POSIX-specs geschreven
waren.
Cron plant in kloktijd, en kloktijd loopt niet door over een zomertijdwissel heen. Twee keer per jaar slaat een klok ergens een uur over of herhaalt hij er een — en een job die in dat uur is ingepland moet iets doen, want "voer hem toch maar uit" heeft geen eenduidige betekenis.
Gaat de klok vooruit, dan bestaan de kloktijden van het overgeslagen uur gewoonweg niet. Een job die op 02:30 staat op de dag dat Europe/Paris van 02:00 naar 03:00 springt, heeft simpelweg geen 02:30 om op te lopen — deze tool meldt die run als overgeslagen in plaats van hem stilletjes naar 01:30 of 03:30 te verplaatsen, want beide gokken zouden minstens zo vaak fout als goed zijn.
Gaat de klok terug, dan komen de kloktijden van het herhaalde uur twee keer voorbij. Deze tool volgt de conventie van elke cron-implementatie die wij kennen: één keer vuren, bij het eerste voorkomen, niet twee keer.
De praktische oplossing is saai maar betrouwbaar: plan onderhoudsjobs buiten het venster van 00:00 tot 04:00 waarin de meeste regio's hun zomertijdwissel leggen, of draai je infrastructuur van begin tot eind op UTC, waar deze hele sectie niet op van toepassing is.
@reboot is geen doelwit voor monitoring@reboot loopt één keer, wanneer de machine opstart — cron garandeert verder
niets en kent er geen "volgende run" voor, want die is er niet. Dat maakt hem
een slechte kandidaat voor het gebruikelijke monitoringpatroon "waarschuw me als
dit niet volgens schema loopt": er is geen schema, dus er is niets waartegen je
stilte kunt afzetten. Doet een @reboot-job er wel toe — het herstellen van
state na een crash, bijvoorbeeld — dan is het meestal die herstelde state die
het bewaken waard is, niet de bootgebeurtenis zelf.
Nee. Er is geen registratie en geen rate-limit die het vermelden waard is, want niets hier praat met een server — het ontleden en het uitrekenen van de volgende runs gebeuren allebei in je browser.
Nee. Niets van wat je typt gaat ergens heen, dus er is niets om te bewaren en niets om bij ons te laten verwijderen.
Een handvol expressies beschrijft een schema dat zelden of nooit vuurt.
0 0 31 2 * (31 februari) matcht nooit met een echte datum en levert nul runs
op. 0 0 29 2 * (29 februari) matcht alleen in schrikkeljaren, dus het kan een
paar jaar zoeken kosten voordat de volgende run bovenkomt.
De extra's in Quartz-stijl die sommige schedulers boven op POSIX-cron zetten:
L (laatste dag), W (dichtstbijzijnde werkdag), # (de n-de weekdag van de
maand) en ? (geen specifieke waarde). Deze tool markeert ze expliciet in plaats
van ze stilletjes verkeerd te lezen als iets anders.
Ja, en het is de moeite waard om na te lopen. Cron op een doorsnee Linux-machine draait in de tijdzone die op het systeem is ingesteld, niet per se UTC en niet per se de jouwe. Kies de zone waarin de crontab van je job daadwerkelijk loopt, niet de zone waarin jij toevallig zit, anders komen de runmomenten die deze tool toont niet overeen met de werkelijkheid.
Deze pagina beantwoordt de vraag "wat doet 30 2 * * 1-5?" — een vraag over de
expressie, beslecht op het moment dat je het antwoord leest. Ze kan je niet
vertellen of de job van vannacht echt gelopen heeft, of hij klaar is gekomen, of
dat cron drie weken geleden stilletjes stopte met vuren omdat iemand de
verkeerde crontab bewerkte.
Heartbeatmonitoring beantwoordt die andere vraag. Je job pingt een unieke URL zodra hij klaar is; blijft die ping langer stil dan het schema plus de respijtperiode toestaat, dan krijg je een melding — e-mail, Slack, webhook, wat je ook gekozen hebt — terwijl het nog om één mislukte run gaat en niet om een week ontbrekende data. Bevestigd vanuit een tweede onafhankelijke EU-proberegio voordat iemand wordt gealarmeerd, zodat een hapering aan onze kant je nooit voor niets wakker maakt.
Het gratis plan dekt 5 checks en verloopt niet.
Zo werkt cron- en heartbeatmonitoring → · Beveiliging & data →