Cron jobs: terugkerende taken plannen op een Linux-server
Kort antwoord
Cron voert commando's uit volgens een schema dat je zelf instelt met vijf tijdvelden plus het commando zelf. Pas je eigen schema aan met crontab -e, of zet een bestand in /etc/cron.d/ voor systeembrede taken. Het meest voorkomende probleem is niet een verkeerd schema, maar een script dat alleen werkt als je het handmatig uitvoert, omdat cron bijna niets van je normale shell-omgeving meekrijgt.
De vijf velden
Een crontab-regel heeft vijf tijdvelden, in deze volgorde, gevolgd door het commando dat moet draaien:
| Veld | Toegestane waarden | Betekenis |
|---|---|---|
| Minuut | 0-59 | Minuut van het uur |
| Uur | 0-23 | Uur van de dag, 24-uursklok |
| Dag van de maand | 1-31 | Dag van de maand |
| Maand | 1-12 | Maand van het jaar |
| Dag van de week | 0-7 (0 en 7 betekenen allebei zondag) | Dag van de week |
Een asterisk (*) betekent "elke waarde" voor dat veld. Een schuine streep stelt een stapgrootte in, dus */15 in het minutenveld betekent elke 15 minuten. Een komma somt specifieke waarden op, en een streepje stelt een bereik in.
Praktijkvoorbeelden
Dit zijn complete, werkende crontab-regels. Het pad naar het script is bewust absoluut, hieronder lees je waarom.
# Run a backup script every day at 3:00am
0 3 * * * /opt/scripts/backup.sh
# Run a health check every 15 minutes
*/15 * * * * /opt/scripts/check.sh
# Run a report on the first day of every month at 6:00am
0 6 1 * * /opt/scripts/monthly-report.shJe crontab bewerken
Crontab per gebruiker
Voer crontab -e uit als de gebruiker van wie je het schema wilt aanpassen. Dit opent de crontab in je standaardeditor. Taken die je hier toevoegt, draaien als die gebruiker, met de rechten van die gebruiker.
Bekijken en verwijderen
Voer crontab -l uit om de crontab van de huidige gebruiker te tonen zonder een editor te openen, en crontab -r om hem volledig te verwijderen. Wees voorzichtig met crontab -r: het verwijdert de hele crontab direct, zonder om bevestiging te vragen. Maak dus eerst een kopie met crontab -l > crontab.bak.
Systeembrede taken
Voor taken die niet bij de crontab van één gebruiker horen, zet je een bestand in /etc/cron.d/. De opmaak is bijna hetzelfde, maar elke regel heeft een extra veld nodig dat aangeeft als welke gebruiker het commando moet draaien:
0 3 * * * root /opt/scripts/backup.shDit is ook de beter vindbare optie binnen configuratiebeheer, omdat het bestand onder versiebeheer staat samen met de rest van je serverconfiguratie, in plaats van in een per-gebruiker-crontab die je makkelijk vergeet.
Waar cron jobs onopgemerkt mislukken
Een script dat perfect werkt als je het zelf in je terminal typt, kan onder cron alsnog mislukken. De reden ligt bijna altijd bij de omgeving, niet bij de logica.
- Minimale omgeving. Cron draait geen login shell, waardoor de shell-profielbestanden die normaal je
PATH, omgevingsvariabelen en aliassen instellen, nooit uitgevoerd worden. Een script datpython3ofnodeaanroept en vertrouwt op dePATHvan je shell om ze te vinden, kan ze onder cron simpelweg niet vinden. - Andere werkmap. Cron-taken starten meestal in de home-directory van de gebruiker die ze draait, niet in de map waar jij toevallig zat toen je het script handmatig testte. Een script dat een relatief pad gebruikt zoals
./data.csvzoekt op de verkeerde plek. - Geen aannames over omgevingsvariabelen. Alles waar je script van afhangt, zoals een API-key of een configuratiepad dat normaal in je shell wordt geëxporteerd, moet je expliciet instellen in het script of de crontab-regel, niet zomaar aannemen dat het al bestaat.
De oplossing is voor het grootste deel hetzelfde: gebruik overal absolute paden, voor het script zelf, voor bestanden die het leest of schrijft, en voor binaries die het aanroept. Ga er niet van uit dat een variabele is ingesteld alleen omdat dat altijd zo is wanneer je het script handmatig draait.
Fouten zichtbaar maken
Standaard mailt cron de output van een taak alleen naar het lokale mailaccount, dat op de meeste servers door niemand wordt gelezen. Een mislukte taak kan wekenlang onopgemerkt blijven, tenzij je een manier inbouwt om het te zien. De simpelste gewoonte is om output naar een logbestand om te leiden:
0 3 * * * /opt/scripts/backup.sh >> /var/log/backup.log 2>&1De 2>&1 stuurt foutmeldingen naar dezelfde plek als de standaarduitvoer, zodat zowel successen als mislukkingen in één bestand terechtkomen dat je kunt checken, of kunt voeden aan een monitoringcheck. Zonder dit zijn cron-mislukkingen standaard onzichtbaar: de taak draait simpelweg niet goed en niets waarschuwt je.