EQVPS
KontrollpanelKom igång

Så schemalägger du uppgifter på en VPS med cron och systemd-timers

Kör säkerhetskopior, städjobb och skript enligt schema. Cron på fem minuter med de tre fällorna som tyst förstör jobb, sedan systemd-timers för loggar, ikapphämtning efter avbrott och exakt tid. Varje beteende nedan testades på en ny Ubuntu 24.04-server.

En server gör sig förtjänt av sin plats genom att arbeta medan du sover: säkerhetskopior, loggrotation, certifikatförnyelse, en rapport klockan nio. Linux har två schemaläggare för det. Cron är fyrtio år gammal och tar en rad. Systemd-timers tar två små filer och ger i gengäld loggar, ikapphämtning efter avbrott och exakt tid. Den här guiden går igenom båda på Ubuntu 24.04, med varje beteende kontrollerat på en ny server från vår avbild, inklusive de tre misstagen som får ett cron-jobb att misslyckas utan ett ord.

Du behöver en användare med sudo; guiden för att sätta upp Ubuntu skapar en.

1. Cron på fem minuter

Cron är installerat och körs på våra Ubuntu- och Debian-avbilder. Varje användare har en jobbtabell; redigera din med:

crontab -e

Varje rad består av fem tidsfält och ett kommando:

# min hour day month weekday  command
  30  3    *   *     *        /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
  */5 *    *   *     *        /usr/local/bin/check.sh
  0   9    *   *     1-5      /usr/local/bin/report.sh
  @reboot                     /usr/local/bin/start-tunnel.sh

Det vill säga: 03:30 varje natt, var 5:e minut, 09:00 på vardagar och en gång efter varje uppstart. */5 betyder vart femte värde, 1-5 ett intervall, 1,15 en lista. Serverns tidszon gäller, UTC på våra avbilder; ställ in din en gång med guiden om värdnamn och tidszon så följer cron.

Se vad som körts med journalctl -u cron. Varje körning loggar användaren och kommandot, och det är där de tre fällorna syns.

Fälla 1: utdatan försvinner. Cron mejlar ett jobbs utdata till användaren. Vår avbild har ingen e-postserver, så journalen visade (CRON) info (No MTA installed, discarding output) och utdatan var borta. Omdirigera den själv, som det första exemplet gör med >> /var/log/backup.log 2>&1.

Fälla 2: procenttecknet. I en crontab avslutar % kommandot och gör resten till standardinmatning. Vi schemalade date +%F > /tmp/today. Journalen visar vad cron faktiskt körde: CMD (date +). Ingen fil skrevs och inget fel nådde oss. Skriv \%, eller lägg kommandot i ett skript och schemalägg skriptet.

Fälla 3: en annan miljö. Cron kör jobb med /bin/sh, inte bash, i din hemkatalog och med en snål miljö. På Ubuntu 24.04 var PATH bättre än sitt rykte: hela systemsökvägen inklusive /usr/local/bin och /snap/bin, för root och för en vanlig användare. Det som fortfarande saknas är allt under din hemkatalog: ~/.local/bin, nvm:s node, pipx, cargo. Använd fullständiga sökvägar i jobbet eller börja raden med . $HOME/.profile;.

Jobb som hör till systemet snarare än en användare läggs i /etc/cron.d/, som en fil med ett extra fält, användaren:

30 3 * * * root /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

Ubuntu kör också allt i /etc/cron.hourly, cron.daily, cron.weekly och cron.monthly, 17 minuter över varje timme, 06:25, 06:47 på söndagar och 06:52 den 1:a. Lägg ett körbart skript där så körs det med resten.

2. Systemd-timers

En timer består av två enheter: en tjänst som gör jobbet och en timer som säger när. Skapa skriptet först, sedan enheterna.

sudo nano /usr/local/bin/backup.sh
sudo chmod +x /usr/local/bin/backup.sh
sudo nano /etc/systemd/system/backup.service
[Unit]
Description=Nightly backup

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
sudo nano /etc/systemd/system/backup.timer
[Unit]
Description=Run the backup every night at 03:30

[Timer]
OnCalendar=*-*-* 03:30
Persistent=true
AccuracySec=1m

[Install]
WantedBy=timers.target

Aktivera timern, inte tjänsten:

sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timers backup.timer

list-timers visar nästa körning, hur långt det är dit och senaste körningen. Loggar kräver ingen inställning: journalctl -u backup.service innehåller varje start, varje slut och varje utdatarad med tidsstämpel. För att köra jobbet direkt, sudo systemctl start backup.service; det är också så du testar skriptet innan du litar på schemat.

Kalendersyntax. OnCalendar läses som veckodag år-månad-dag timme:minut:sekund, med * för vilket värde som helst. Testa ett uttryck innan du använder det:

systemd-analyze calendar "Mon..Fri *-*-* 03:00" --iterations 2

Det skriver ut den normaliserade formen och nästa datum. Några uttryck vi kontrollerade:

OnCalendarBetydelse
*-*-* 03:30Varje dag 03:30
Mon..Fri *-*-* 09:00Vardagar 09:00
*:0/15Var 15:e minut
weeklyMåndagar 00:00
*-*-01 04:00Den 1:a varje månad 04:00
*-*-* 03:00 Europe/Kyiv03:00 Kyiv-tid; kördes 01:00 UTC hos oss

De tre inställningarna värda att kunna. Persistent=true sparar senaste körningen på disk och hämtar ikapp en körning som missades medan servern var avstängd eller timern stoppad. Vi stoppade vår timer som körs varannan minut, väntade förbi en schemalagd körning och startade den igen: den missade körningen startade inom samma sekund. Utan Persistent väntar den helt enkelt på nästa tillfälle.

AccuracySec är överraskningen. Systemd grupperar som standard timers inom ett fönster på en minut för att spara väckningar, så vår första körning kom 07:42:18, inte 07:42:00. Med AccuracySec=1s hamnade nästa körningar på sekunden 07:46:00 och 07:48:00. Sätt den när minuten spelar roll; behåll standardvärdet för en nattlig säkerhetskopia.

RandomizedDelaySec=10m gör medvetet tvärtom: den sprider starten över ett fönster så att tio servrar inte träffar samma lagring för säkerhetskopior i samma sekund.

För ett engångsjobb behövs inga filer alls:

sudo systemd-run --on-active=30m --unit=cleanup-once /usr/local/bin/cleanup.sh

Det skapar en tillfällig timer som utlöses en gång och försvinner; fram till dess visar systemctl list-timers den.

3. Vilken du ska välja

CronSystemd-timer
Inställning1 rad2 filer
LoggarBara om du omdirigerar utdatajournalctl -u name.service
Missad körning medan servern var avstängdFörloradKörs vid uppstart med Persistent=true
Jobbet körs fortfarande vid nästa tickEn andra kopia startarHoppas över tills den första är klar
Exakt tidPå minutenPå sekunden med AccuracySec=1s
StatusIngenlist-timers, systemctl status

Använd cron för en snabb rad som du känner igen om ett år. Använd en timer för allt vars fel du behöver se, som inte får överlappa eller som måste köras efter en missad omstart: säkerhetskopior, certifikatförnyelse, databasstädning. Om ett cron-jobb kan överlappa, linda in det: flock -n /tmp/backup.lock /usr/local/bin/backup.sh, så avslutas den andra kopian direkt.

Båda schemaläggarna startar ett jobb och slutar. För ett program som ska gå dygnet runt och komma tillbaka efter en krasch behöver du en tjänst, inte ett schema; se hur du skapar en systemd-tjänst och för Windows hur du kör ett skript 24/7 på Windows Server. En bra första timer är den från vår guide för säkerhetskopiering med restic; automatiska säkerhetsuppdateringar är en timer som Ubuntu redan levererar, apt-daily-upgrade.timer, en av de 17 som körs på en ny server.

FAQ

Varför fungerar mitt jobb i terminalen men inte i cron?

Tre vanliga skäl. Cron kör jobbet med sh, inte bash, så bash-specifik syntax misslyckas. Verktyg i din hemkatalog, som nvm, pipx eller cargo, finns inte i crons PATH, så använd fullständiga sökvägar. Och varje % på kommandoraden avslutar kommandot: date +%F blev date + på vår server. Skriv det som \% eller flytta kommandot till ett skript.

Vart tar cron-utdata vägen?

Till e-post, som standard. Vår avbild har ingen e-postserver, så cron loggar 'No MTA installed, discarding output' och utdatan försvinner. Lägg till >> /var/log/myjob.log 2>&1 i jobbet, eller byt till en systemd-timer, vars utdata hamnar i journalen av sig själv.

Vad är fördelen med en systemd-timer jämfört med cron?

Loggar i journalctl, ingen andra kopia av ett jobb som fortfarande körs, ikapphämtning med Persistent=true av körningar som missades medan servern var avstängd, och en statusrad med nästa och senaste körning. Cron vinner på korthet: en rad i stället för två filer.

Min timer startade 18 sekunder för sent. Varför?

Som standard grupperar systemd timers inom ett fönster på en minut för att spara väckningar, det är inställningen AccuracySec. Vår timer som körs varannan minut startade 07:42:18 i stället för 07:42:00. Med AccuracySec=1s startade den exakt 07:46:00. Sätt den när den exakta minuten spelar roll.

Vilken tidszon använder cron och timers?

Serverns, som är UTC på våra avbilder. Ställ in den en gång med timedatectl, se vår guide om värdnamn och tidszon, så följer både cron och timers den. En timer kan också ha en egen zon: OnCalendar=*-*-* 03:00 Europe/Kyiv kördes 01:00 UTC i vårt test.

Kommentarer

Inga kommentarer än. Bli först.

Lämna en kommentar

Kommentarer modereras innan de visas.