Hoe je een cron-expressie leest
Een cron-expressie bestaat uit vijf waarden gescheiden door spaties, van links naar rechts gelezen als minuut, uur, dag van de maand, maand, dag van de week. De taak draait wanneer de huidige tijd op elk veld past.
30 4 * * 1
│ │ │ │ │
│ │ │ │ └── day of week (1 = Monday)
│ │ │ └──── month (any)
│ │ └────── day of month (any)
│ └──────── hour (4am)
└─────────── minute (30)
Die leest als "om 04:30 elke maandag".
De vijf velden
| # | Veld | Toegestane waarden | Opmerkingen |
|---|---|---|---|
| 1 | Minuut | 0 tot 59 | |
| 2 | Uur | 0 tot 23 | 24-uursklok, 0 is middernacht |
| 3 | Dag van de maand | 1 tot 31 | |
| 4 | Maand | 1 tot 12, of JAN tot DEC | |
| 5 | Dag van de week | 0 tot 6, of SUN tot SAT | 0 is zondag, en de meeste cron-implementaties accepteren ook 7 |
Sommige planners gebruiken een andere vorm. Quartz, dat veel Java-software gebruikt, zet seconden vooraan en voegt een optioneel jaar toe, en nummert de weekdagen 1 tot 7 beginnend bij zondag. Heeft een expressie zes of zeven velden, controleer dan voor welk systeem hij geschreven is voordat je op je eigen lezing vertrouwt.
De operatoren
Er zijn er vier, en ze zijn binnen één veld te combineren.
| Symbool | Naam | Voorbeeld | Betekenis |
|---|---|---|---|
* | Elke | * * * * * | Elke minuut van elke dag |
, | Lijst | 0 9,13,17 * * * | Om 09:00, 13:00 en 17:00 |
- | Bereik | 0 9-17 * * * | Elk uur van 09:00 tot en met 17:00 |
/ | Stap | */15 * * * * | Op :00, :15, :30 en :45 |
Een stap wordt altijd op een bereik toegepast. */15 in het minutenveld betekent "begin bij 0 en neem elke 15e waarde tot 59". Je kunt ook een expliciet bereik in stappen doorlopen: 5-30/10 geeft 5, 15 en 25, en stopt dan omdat 35 voorbij het einde ligt.
Stappen betekenen niet "elke 15 minuten vanaf nu"; ze selecteren vaste waarden van de klok. */40 gaat af op :00 en :40, en wacht dan maar 20 minuten tot de :00 van het volgende uur, omdat het tellen elk uur opnieuw begint. Lijsten kunnen bereiken en stappen bevatten, dus 0 0-6/2,12,18-23 * * * is een geldig uurveld.
Namen en snelkoppelingen
De velden voor maand en dag van de week accepteren namen van drie letters, en hoofdlettergebruik doet er niet toe, dus JAN, jan en Jan zijn hetzelfde. De klassieke crontab-documentatie zegt dat bereiken en lijsten van namen niet zijn toegestaan, al accepteren veel moderne implementaties MON-FRI wel. Weet je niet zeker wat je taak uitvoert, gebruik dan cijfers: 1-5 is overal eenduidig.
Een aantal snelkoppelingen vervangt de hele expressie van vijf velden:
| Snelkoppeling | Gelijk aan | Draait |
|---|---|---|
@yearly of @annually | 0 0 1 1 * | Middernacht, 1 januari |
@monthly | 0 0 1 * * | Middernacht, de 1e van de maand |
@weekly | 0 0 * * 0 | Middernacht op zondag |
@daily of @midnight | 0 0 * * * | Elke dag om middernacht |
@hourly | 0 * * * * | Op het hele uur |
@reboot bestaat ook, maar dat is geen schema: het draait de taak één keer wanneer cron zelf start.
De valstrik met dag van de maand en dag van de week
Dit is de valstrik die toeslaat. Wanneer zowel het veld voor de dag van de maand als dat voor de dag van de week beperkt is, dus geen van beide * is, draait cron de taak wanneer een van beide past, niet wanneer ze allebei passen.
0 0 13 * 5
Je zou dat kunnen lezen als "middernacht op vrijdag de dertiende". Het betekent eigenlijk "middernacht op de 13e van elke maand, en ook middernacht elke vrijdag": meer dan zestig uitvoeringen per jaar in plaats van een of twee.
Het EN-gedrag dat je verwachtte geldt alleen wanneer een van de twee velden * is. Dus 0 0 * * 5 is elke vrijdag en 0 0 13 * * is elke 13e, allebei volstrekt normaal. Het is het beperken van beide velden dat de OF in gang zet.
Er is geen standaardmanier om "vrijdag de dertiende" in vijf velden uit te drukken. De gebruikelijke omweg is om elke 13e in te plannen en de taak de weekdag te laten controleren voordat hij iets doet.
Een verwante subtiliteit: sommige implementaties bepalen of een veld beperkt is door te kijken of het letterlijk met * begint. Onder die implementaties telt 0-6 in het veld voor de dag van de week als beperkt, ook al dekt het elke dag, waarmee stilletjes het OF-gedrag aangaat. Gebruik * wanneer je "elke" bedoelt.
Fouten die het controleren waard zijn
* */2 * * *draait elke minuut tijdens elk tweede uur: 720 keer per dag. Je wilde0 */2 * * *, wat er 12 zijn.- Een ontbrekend minutenveld schuift alles één plek naar links en parst meestal nog steeds, waarmee je een geldig schema op een volstrekt verkeerd tijdstip krijgt.
0 0 31 * *slaat stilzwijgend de maanden zonder 31e over.- Cron gebruikt de tijdzone van het systeem of van de gebruiker, tenzij de planner je er een laat instellen. Wanneer de klok voor de zomertijd verspringt, draait een taak in het overgeslagen uur mogelijk helemaal niet en een taak in het herhaalde uur mogelijk twee keer, afhankelijk van de implementatie. Taken die één keer per dag moeten draaien plan je het veiligst weg van de nachtelijke uren waarin die verschuiving valt.
Lees bij twijfel de expressie terug als een zin, en controleer dan de eerstvolgende paar momenten waarop hij daadwerkelijk zou afgaan. Zijn die datums niet wat je beschreef, dan is de expressie fout en niet je lezing ervan.