Cron-expressies: de vijf velden, met voorbeelden
Een cron-expressie bestaat uit vijf door spaties gescheiden velden die zeggen wanneer een taak draait: minuut, uur, dag van de maand, maand, dag van de week. Van links naar rechts gelezen betekent 30 2 * * 1: op minuut 30 van uur 2 op elke dag van elke maand, als die dag een maandag is.
De vijf velden
Elke standaard Unix-cronregel begint met dezelfde vijf velden, gevolgd door het uit te voeren commando.
* * * * * command to run
| | | | |
| | | | +-- day of week (0-7, 0 and 7 both mean Sunday, or SUN-SAT)
| | | +---- month (1-12, or JAN-DEC)
| | +------ day of month (1-31)
| +-------- hour (0-23)
+---------- minute (0-59)
Een veld bevat een van vier dingen: een sterretje dat elke waarde betekent, een enkel getal, een lijst, of een bereik. Uren gebruiken een 24-uursklok zonder AM of PM, dus 18.00 uur is 18. Zondag is zowel 0 als 7 omdat verschillende systemen het historisch oneens waren, en cron accepteert beide.
Sommige schedulers voegen velden toe. Quartz, gebruikt door veel Java-frameworks, zet een secondenveld vooraan en voegt aan het eind een optioneel jaar toe, dus een expressie van zes of zeven velden gekopieerd uit een Quartz-referentie werkt niet in een Linux-crontab. Controleer voor welke variant u schrijft voordat u ergens een expressie vandaan kopieert.
De speciale tekens
*komt overeen met elke waarde in het veld.* * * * *draait elke minuut.,geeft een lijst met waarden.0 8,13,20 * * *draait om 08:00, 13:00 en 20:00.-geeft een bereik.0 9-17 * * *draait elk uur van 09:00 tot en met 17:00./neemt een stap door een bereik.*/15 * * * *draait op minuut 0, 15, 30 en 45. U kunt het combineren met een bereik:0 9-17/2 * * *draait om 9, 11, 13, 15 en 17 uur.- Namen.
MONtot en metSUNenJANtot en metDECwerken in de laatste twee velden en lezen beter dan getallen. Ze kunnen niet binnen een stap worden gebruikt.
Vier andere tekens duiken voortdurend op in tutorials en bestaan niet in standaard-cron. L voor de laatste dag, W voor de dichtstbijzijnde werkdag, # voor de n-de weekdag van de maand, en ? in plaats van een sterretje zijn Quartz-uitbreidingen. Een expressie zoals 0 0 L * * wordt door een Linux-crontab geweigerd. Om daar iets op de laatste dag van de maand te draaien, draait u het dagelijks en laat u het commando beslissen:
0 0 * * * [ "$(date -d tomorrow +\%d)" = "01" ] && /usr/local/bin/month-end.sh
Let op de backslashes in die regel. Een procentteken heeft een speciale betekenis in een crontab, wat de vijfde fout hieronder is.
Cron accepteert ook zes verkorte notaties in plaats van alle vijf velden: @yearly (ook geschreven als @annually), @monthly, @weekly, @daily (ook @midnight), @hourly, en @reboot, dat eenmalig draait wanneer cron start in plaats van op een klok. @reboot wordt niet overal ondersteund.
Veelvoorkomende schema's
| Wanneer u het wilt laten draaien | Expressie |
|---|---|
| Elke minuut | * * * * * |
| Elke 5 minuten | */5 * * * * |
| Elke 30 minuten | 0,30 * * * * |
| Elk uur, op het hele uur | 0 * * * * |
| Elke 2 uur | 0 */2 * * * |
| Elke dag om middernacht | 0 0 * * * |
| Elke dag om 02:30 | 30 2 * * * |
| Tweemaal per dag, 08:00 en 20:00 | 0 8,20 * * * |
| Doordeweeks om 09:00 | 0 9 * * MON-FRI |
| Elk uur tijdens kantooruren, doordeweeks | 0 9-17 * * MON-FRI |
| Elke maandag om 07:00 | 0 7 * * MON |
| Elke zondag om 03:15 | 15 3 * * SUN |
| Eerste van de maand om 06:00 | 0 6 1 * * |
| Per kwartaal, eerste van jan, apr, jul, okt | 0 0 1 1,4,7,10 * |
Fouten die de taak op het verkeerde moment laten draaien
- Beide dagvelden invullen. Dit is degene waar iedereen intrapt. Wanneer dag van de maand en dag van de week allebei op iets anders dan een sterretje staan, draait cron de taak wanneer een van beide overeenkomt, niet allebei.
0 0 13 * FRIdraait op elke 13e en op elke vrijdag, niet op vrijdag de 13e. - Een stap die niet gelijk opdeelt in het bereik.
*/7 * * * *gaat af op minuten 0, 7, 14, 21, 28, 35, 42, 49 en 56, en begint dan opnieuw bij 0. Het gat over de uurgrens heen is vier minuten, geen zeven. Dezelfde valkuil geldt voor*/40in het minutenveld en elke stap die geen deler is van 60. - De stap in het verkeerde veld zetten.
*/2 * * * *is elke twee minuten.0 */2 * * *is elke twee uur. De voorloop-0weglaten maakt van een taak per uur een taak die 30 keer zo vaak draait. - De omgeving als vanzelfsprekend aannemen. Cron geeft de taak een minimale omgeving, meestal weinig meer dan
PATH=/usr/bin:/binenSHELL=/bin/sh. Een script dat in uw shell werkt, faalt in cron omdat het iets aanroept in/usr/local/bin. Gebruik absolute paden voor het commando en erbinnen. - Een niet-geëscapet procentteken. In een crontab wordt
%omgezet in een nieuwe regel, en alles na de eerste wordt aan het commando gevoerd als standaardinvoer. Eendate +%Y-%m-%dbinnen een crontabregel moet geschreven worden alsdate +\%Y-\%m-\%d. - De uitvoer negeren. Alles wat de taak afdrukt, wordt gemaild naar de eigenaar van de crontab, en op een machine zonder mailconfiguratie wordt het weggegooid. Stuur het ergens naartoe waar u het leest:
0 3 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1 - Runs laten overlappen. Cron start de volgende run op schema, of de vorige nu klaar is of niet. Wikkel lange taken in een lock:
*/5 * * * * flock -n /tmp/sync.lock /usr/local/bin/sync.sh - De klokverzetting vergeten. Cron gebruikt de lokale tijd van de machine. Op de dagen dat de klok verzet, bestaat het uur rond 02:00 ofwel niet, ofwel gebeurt het twee keer, dus een taak die daarbinnen gepland staat, kan worden overgeslagen of twee keer draaien, afhankelijk van de cron-implementatie. Zet servers op UTC, of plan buiten dat venster.
crontab -rtypen. Het verwijdert de hele crontab zonder bevestiging, en het zit één toets naastcrontab -e. Houd de crontab in versiebeheer en installeer hem vanuit een bestand.
Controleer het van buitenaf
Een expressie die geldig parseert is niet hetzelfde als een taak die daadwerkelijk draaide. Controleer beide, op de machine en dan vanaf buiten.
Bevestig op de machine wat er geïnstalleerd is, wat de klok zegt, en of cron de taak startte:
crontab -l
timedatectl
grep CRON /var/log/syslog | tail -20
journalctl -u cron -u crond --since "2 hours ago"
De logregel bewijst dat cron het commando startte. Ze zegt niets over of het commando slaagde, en dat is waarom de omleiding naar een logbestand uit de fouten hierboven ertoe doet.
Controleer vervolgens het resultaat zoals een gebruiker dat zou doen, van buiten de server. De meeste geplande taken bestaan om iets waarneembaars te veranderen: een feed die de datum van vandaag zou moeten dragen, een sitemap die herschreven had moeten zijn, een export die verschenen had moeten zijn. Vraag het op en lees de headers:
curl -sI https://example.com/exports/daily.json
curl -s https://example.com/health/last-run
De header Last-Modified vertelt u of het bestand vers is, en dat doet ze zonder shell-toegang. Hetzelfde verzoek vanaf meerdere locaties uitvoeren met de HTTP-check onderscheidt een taak die niet draaide van een pagina die op een edge in één regio gecachet en alleen daar verouderd is. Dat onderscheid is onzichtbaar vanaf één curl op de server zelf.
Weten wanneer een geplande taak stopt met draaien
Een cron-taak die stopt met draaien, levert niets op om op te merken. Er is geen foutpagina en geen mislukt verzoek, dus niets slaat alarm tenzij iets de afwezigheid in de gaten houdt. Wat u monitort is het effect van de taak in plaats van de taak zelf: een statusbestand dat ze herschrijft, een tijdstempel die ze publiceert, een endpoint dat de laatst geslaagde run meldt. Een geplande check tegen dat endpoint maakt van een stille mislukking een melding, en HostTracker stuurt die per e-mail, sms, spraakoproep, Slack, Telegram en meer over 13 monitortypen. De mechanica van het opzetten daarvan staat in de handleiding HTTP-check, de rest van de probleemoplossingshandleidingen staat in het onderdeel oplossen, en de volledige lijst met checktypen staat op de functiespagina.