Vad är Cron?

Cron är ett Unix-baserat system för att schemalägga återkommande tasks (jobs). Namnet kommer från grekiskans “chronos” (tid). Cron expressions är den syntax som används för att definiera när dessa tasks ska köras.

Grundläggande syntax

En cron expression består av 5 eller 6 fält:

* * * * * command
│ │ │ │ │
│ │ │ │ └─── Veckodag (0-7) (0 och 7 = Söndag)
│ │ │ └───── Månad (1-12)
│ │ └─────── Dag i månaden (1-31)
│ └───────── Timme (0-23)
└─────────── Minut (0-59)

Med sekunder (vissa system):

* * * * * * command
│ │ │ │ │ │
│ │ │ │ │ └─── Veckodag (0-7)
│ │ │ │ └───── Månad (1-12)
│ │ │ └─────── Dag (1-31)
│ │ └───────── Timme (0-23)
│ └─────────── Minut (0-59)
└───────────── Sekund (0-59)

Special Characters

Asterisk (*)

Matchar alla värden

* * * * *
# Varje minut

Komma (,)

Lista av värden

0 9,12,15 * * *
# Kl 09:00, 12:00, och 15:00

Bindestreck (-)

Intervall av värden

0 9-17 * * *
# Varje timme från 9:00 till 17:00

Snedstreck (/)

Steg-värden

*/15 * * * *
# Var 15:e minut (0, 15, 30, 45)

0 */2 * * *
# Varannan timme

Question Mark (?)

Ingen specifik värde (dag eller veckodag)

0 0 15 * ?
# 15:e dagen varje månad, oavsett veckodag

L (Last)

Sista dagen i månaden

0 0 L * *
# Midnatt på sista dagen i månaden

W (Weekday)

Närmaste vardag

0 0 15W * *
# Närmaste vardag till den 15:e

Hash (#)

N:te veckodag i månaden

0 0 * * 1#2
# Andra måndagen i månaden

Vanliga exempel

Varje minut

* * * * *

Var 5:e minut

*/5 * * * *

Varje timme

0 * * * *

Varje dag kl 00:00

0 0 * * *

Varje måndag kl 09:00

0 9 * * 1

Första dagen varje månad

0 0 1 * *

Varje vardag kl 17:00

0 17 * * 1-5

Varje helg kl 10:00

0 10 * * 0,6

Varannan timme mellan 9-17

0 9-17/2 * * *
# 09:00, 11:00, 13:00, 15:00, 17:00

Var 15:e minut under kontorstid

*/15 9-17 * * 1-5

Praktiska Use Cases

1. Backup varje natt

# Full backup kl 02:00 varje natt
0 2 * * * /scripts/backup.sh

# Incrementell backup var 6:e timme
0 */6 * * * /scripts/incremental-backup.sh

2. Database Cleanup

# Radera gamla loggar varje söndag kl 03:00
0 3 * * 0 /scripts/cleanup-logs.sh

# Optimera databas första dagen varje månad
0 4 1 * * /scripts/optimize-db.sh

3. Report Generation

# Daglig rapport kl 08:00 varje vardag
0 8 * * 1-5 /scripts/daily-report.sh

# Veckorapport varje fredag kl 17:00
0 17 * * 5 /scripts/weekly-report.sh

# Månadsrapport sista dagen i månaden
0 18 L * * /scripts/monthly-report.sh

4. Monitoring & Health Checks

# Kolla server health var 5:e minut
*/5 * * * * /scripts/health-check.sh

# Skicka metrics varje timme
0 * * * * /scripts/send-metrics.sh

5. Cache Clearing

# Rensa cache kl 03:00 varje natt
0 3 * * * /scripts/clear-cache.sh

# Rensa temp files var 12:e timme
0 */12 * * * rm -rf /tmp/*

Crontab Management

Visa aktuell crontab

crontab -l

Redigera crontab

crontab -e

Ta bort crontab

crontab -r

Crontab för specifik användare

sudo crontab -u username -e

Crontab syntax

# m h dom mon dow command
# Kommentarer börjar med #

# Variabler
SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin
MAILTO=admin@example.com

# Jobs
0 2 * * * /scripts/backup.sh
*/15 * * * * /scripts/health-check.sh

Environment Variables

Cron jobs körs i begränsad environment:

# ❌ Fungerar inte - PATH är begränsad
0 2 * * * node /app/script.js

# ✅ Använd full path
0 2 * * * /usr/local/bin/node /app/script.js

# ✅ Eller sätt PATH
PATH=/usr/local/bin:/usr/bin:/bin
0 2 * * * node /app/script.js

# ✅ Source profile
0 2 * * * source ~/.bashrc && node /app/script.js

Logging

# Logga till fil
0 2 * * * /scripts/backup.sh >> /var/log/backup.log 2>&1

# Skicka fel via email (om MAILTO är satt)
0 2 * * * /scripts/backup.sh 2>&1

# Tyst output
0 2 * * * /scripts/backup.sh > /dev/null 2>&1

# Logga med timestamp
0 2 * * * echo "$(date): Backup started" >> /var/log/backup.log && /scripts/backup.sh

Olika Cron-varianter

Standard Unix Cron (5 fält)

* * * * * command

Cron med sekunder (6 fält) - Vissa system

* * * * * * command

Quartz Cron (används i Java/Spring)

# 7 fält: sekund minut timme dag månad veckodag år
0 0 12 * * ? 2024

systemd timers (Linux alternativ)

[Timer]
OnCalendar=daily
OnCalendar=Mon *-*-* 00:00:00

Special Strings

Vissa cron-implementationer stöder special strings:

@yearly   # 0 0 1 1 *
@annually # 0 0 1 1 *
@monthly  # 0 0 1 * *
@weekly   # 0 0 * * 0
@daily    # 0 0 * * *
@midnight # 0 0 * * *
@hourly   # 0 * * * *
@reboot   # Kör vid boot

Exempel:

@daily /scripts/backup.sh
@reboot /scripts/startup.sh
@hourly /scripts/health-check.sh

Node.js med node-cron

const cron = require('node-cron');

// Varje minut
cron.schedule('* * * * *', () => {
  console.log('Running every minute');
});

// Varje dag kl 00:00
cron.schedule('0 0 * * *', () => {
  console.log('Daily task');
});

// Varje måndag kl 09:00
cron.schedule('0 9 * * 1', () => {
  console.log('Monday morning task');
});

// Med timezone
cron.schedule('0 9 * * *', () => {
  console.log('Running at 9 AM Stockholm time');
}, {
  timezone: "Europe/Stockholm"
});

GitHub Actions Cron

name: Daily Task
on:
  schedule:
    # Varje dag kl 00:00 UTC
    - cron: '0 0 * * *'
    # Varje måndag kl 09:00 UTC
    - cron: '0 9 * * 1'

OBS: GitHub Actions använder UTC!

AWS EventBridge (CloudWatch Events)

{
  "scheduleExpression": "cron(0 12 * * ? *)",
  "description": "Run daily at 12:00 PM UTC"
}

Format: cron(Minut Timme Dag Månad Veckodag År)

Common Pitfalls

1. Timezone confusion

# Cron använder systemets timezone
0 9 * * *  # 9 AM i serverns timezone

# För specifik timezone (systemd)
OnCalendar=Europe/Stockholm:Mon *-*-* 09:00:00

2. Path-problem

# ❌ Kommandot hittas inte
0 2 * * * mycommand

# ✅ Använd absolut path
0 2 * * * /usr/local/bin/mycommand

3. Dag och veckodag kombination

# Kör 15:e ELLER måndag (inte 15:e som är måndag)
0 0 15 * 1

# För 15:e som är måndag, använd script-logik

4. Inget error output

# ❌ Fel syns inte
0 2 * * * /scripts/backup.sh

# ✅ Logga fel
0 2 * * * /scripts/backup.sh 2>&1 | tee -a /var/log/backup.log

5. Overlapping jobs

# Om backup tar > 1 timme, kommer nästa start samtidigt
0 * * * * /scripts/long-backup.sh

# Lösning: Använd lockfile
0 * * * * flock -n /tmp/backup.lock /scripts/long-backup.sh

Testing Cron Expressions

Online validators

  • crontab.guru
  • crontab-generator.org
  • freeformatter.com/cron-expression-generator

Lokalt testing

# Kör kommando direkt
/usr/bin/php /path/to/script.php

# Simulera cron environment
env -i /bin/sh -c '/path/to/script.sh'

# Testa nästa 5 körningar
crontab -l | grep "backup" | while read line; do
  echo "Next 5 runs:"
  echo "$line" | # Use cron analyzer tool
done

Best Practices

1. Använd absolute paths

# ✅ Bra
0 2 * * * /usr/local/bin/node /home/user/app/script.js

# ❌ Dåligt
0 2 * * * node script.js

2. Alltid logga

0 2 * * * /scripts/backup.sh >> /var/log/backup.log 2>&1

3. Sätt MAILTO

MAILTO=admin@example.com
0 2 * * * /scripts/backup.sh

4. Kommentera dina cron jobs

# Daily backup at 2 AM
0 2 * * * /scripts/backup.sh

# Weekly report every Monday at 9 AM
0 9 * * 1 /scripts/weekly-report.sh

5. Använd lockfiles för långvariga jobs

0 * * * * flock -n /tmp/myjob.lock -c '/scripts/long-job.sh'

6. Monitorera cron jobs

# Skicka heartbeat till monitoring
0 2 * * * /scripts/backup.sh && curl https://monitor.com/ping/backup

Debugging

Kolla om cron körs

sudo systemctl status cron
# eller
sudo service cron status

Kolla cron logs

grep CRON /var/log/syslog
# eller
journalctl -u cron

Verifiera syntax

# Online: crontab.guru
# eller använd vårt verktyg

Testa direkt

# Kör som cron skulle (utan environment)
env -i /bin/sh -c 'echo $PATH'

Verktyg

Testa och validera cron expressions:

Slutsats

Kom ihåg:

  • ✅ Använd absolute paths
  • ✅ Logga alltid output
  • ✅ Kommentera dina jobs
  • ✅ Testa innan deploy
  • ✅ Monitorera körningar
  • ⚠️ Tänk på timezone
  • ⚠️ Hantera overlapping jobs

Cron är kraftfullt men kräver omsorg - välskriven automation sparar tid, dåligt skriven skapar problem!