Un server își merită banii lucrând cât dormi: backupuri, rotirea logurilor, reînnoirea certificatelor, un raport la ora nouă. Linux are pentru asta două programatoare. Cron are patruzeci de ani și încape într-o linie. Timerele systemd cer două fișiere mici și oferă în schimb loguri, recuperare după oprire și oră exactă. Ghidul acesta le acoperă pe amândouă pe Ubuntu 24.04, cu fiecare comportament verificat pe un server nou din imaginea noastră, inclusiv cele trei greșeli care fac un job cron să eșueze fără niciun cuvânt.
Ai nevoie de un utilizator cu sudo; ghidul de configurare Ubuntu creează unul.
1. Cron în cinci minute
Cron e instalat și pornit pe imaginile noastre Ubuntu și Debian. Fiecare utilizator are un tabel de joburi; editează-l pe al tău cu:
crontab -e
Fiecare linie are cinci câmpuri de timp și o comandă:
# 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
Adică: la 03:30 în fiecare noapte, la fiecare 5 minute, la 09:00 în zilele lucrătoare și o dată după fiecare pornire. */5 înseamnă fiecare a cincea valoare, 1-5 un interval, 1,15 o listă. Se aplică fusul orar al serverului, UTC pe imaginile noastre; setează-l pe al tău o dată cu ghidul despre hostname și fus orar, iar cron îl urmează.
Vezi ce a rulat cu journalctl -u cron. Fiecare rulare înregistrează utilizatorul și comanda, și acolo apar cele trei capcane.
Capcana 1: ieșirea dispare. Cron trimite pe email ieșirea unui job către utilizator. Imaginea noastră nu are server de mail, așa că jurnalul a scris (CRON) info (No MTA installed, discarding output) și ieșirea s-a pierdut. Redirecționeaz-o singur, cum face primul exemplu cu >> /var/log/backup.log 2>&1.
Capcana 2: semnul procent. Într-un crontab, % încheie comanda și transformă restul în intrare standard. Am programat date +%F > /tmp/today. Jurnalul arată ce a rulat de fapt cron: CMD (date +). Nu s-a scris niciun fișier și nicio eroare n-a ajuns la noi. Scrie \% sau pune comanda într-un script și programează scriptul.
Capcana 3: alt mediu. Cron rulează joburile cu /bin/sh, nu bash, în directorul tău home și cu un mediu restrâns. Pe Ubuntu 24.04 PATH-ul a fost mai bun decât reputația lui: calea completă de sistem, inclusiv /usr/local/bin și /snap/bin, pentru root și pentru un utilizator obișnuit. Ce lipsește în continuare e tot ce se află în home: ~/.local/bin, node-ul din nvm, pipx, cargo. Folosește căi complete în job sau începe linia cu . $HOME/.profile;.
Joburile care țin de sistem, nu de un utilizator, merg în /etc/cron.d/, ca fișier cu un câmp în plus, utilizatorul:
30 3 * * * root /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
Ubuntu rulează și tot ce se află în /etc/cron.hourly, cron.daily, cron.weekly și cron.monthly, la minutul 17 al fiecărei ore, la 06:25, duminica la 06:47 și pe 1 ale lunii la 06:52. Pune acolo un script executabil și va rula împreună cu celelalte.
2. Timerele systemd
Un timer înseamnă două unități: un serviciu care face treaba și un timer care spune când. Creează întâi scriptul, apoi unitățile.
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
Activează timerul, nu serviciul:
sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timers backup.timer
list-timers arată următoarea rulare, cât mai e până la ea și ultima rulare. Logurile nu cer configurare: journalctl -u backup.service conține fiecare pornire, fiecare final și fiecare linie de ieșire, cu oră. Ca să rulezi jobul imediat, sudo systemctl start backup.service; tot așa testezi scriptul înainte să te bazezi pe program.
Sintaxa calendarului. OnCalendar se citește ziua-săptămânii an-lună-zi oră:minut:secundă, cu * pentru orice valoare. Testează o expresie înainte s-o folosești:
systemd-analyze calendar "Mon..Fri *-*-* 03:00" --iterations 2
Afișează forma normalizată și următoarele date. Câteva expresii pe care le-am verificat:
| OnCalendar | Înseamnă |
|---|---|
*-*-* 03:30 | Zilnic la 03:30 |
Mon..Fri *-*-* 09:00 | În zilele lucrătoare la 09:00 |
*:0/15 | La fiecare 15 minute |
weekly | Lunea la 00:00 |
*-*-01 04:00 | Pe 1 ale fiecărei luni la 04:00 |
*-*-* 03:00 Europe/Kyiv | 03:00 ora Kievului; la noi a rulat la 01:00 UTC |
Cele trei setări de știut. Persistent=true salvează ultima rulare pe disc și recuperează o rulare ratată cât serverul a fost oprit sau timerul oprit. Am oprit timerul nostru de la două minute, am așteptat să treacă o rulare programată și l-am pornit din nou: rularea ratată a pornit în aceeași secundă. Fără Persistent, așteaptă pur și simplu următorul interval.
AccuracySec e surpriza. Implicit, systemd grupează timerele într-o fereastră de un minut ca să economisească treziri, așa că prima noastră rulare a venit la 07:42:18, nu la 07:42:00. Cu AccuracySec=1s, următoarele au căzut la secundă pe 07:46:00 și 07:48:00. Setează-l când contează minutul; lasă valoarea implicită pentru un backup de noapte.
RandomizedDelaySec=10m face intenționat invers: împrăștie pornirea într-o fereastră ca zece servere să nu lovească același spațiu de backup în aceeași secundă.
Pentru un job unic, nu trebuie niciun fișier:
sudo systemd-run --on-active=30m --unit=cleanup-once /usr/local/bin/cleanup.sh
Creează un timer temporar care pornește o dată și dispare; până atunci îl arată systemctl list-timers.
3. Pe care să-l alegi
| Cron | Timer systemd | |
|---|---|---|
| Configurare | 1 linie | 2 fișiere |
| Loguri | Doar dacă redirecționezi ieșirea | journalctl -u name.service |
| Rulare ratată cât serverul era oprit | Pierdută | Rulează la pornire cu Persistent=true |
| Jobul încă rulează la următorul tic | Pornește a doua copie | Sărit până termină prima |
| Oră exactă | La minut | La secundă cu AccuracySec=1s |
| Stare | Niciuna | list-timers, systemctl status |
Folosește cron pentru o linie rapidă pe care o recunoști și peste un an. Folosește un timer pentru tot ce trebuie să vezi când eșuează, ce nu are voie să se suprapună sau ce trebuie să ruleze după un restart ratat: backupuri, reînnoirea certificatelor, curățarea bazelor de date. Dacă un job cron se poate suprapune, înfășoară-l: flock -n /tmp/backup.lock /usr/local/bin/backup.sh, iar a doua copie iese imediat.
Ambele programatoare pornesc un job și se opresc. Pentru un program care trebuie să meargă non-stop și să revină după o cădere ai nevoie de un serviciu, nu de un program orar; vezi cum creezi un serviciu systemd și, pentru Windows, cum rulezi un script 24/7 pe Windows Server. Un prim timer bun este cel din ghidul nostru de backup cu restic; actualizările automate de securitate sunt un timer pe care Ubuntu îl are deja, apt-daily-upgrade.timer, unul dintre cele 17 care rulează pe un server nou.
Comentarii
Încă nu există comentarii. Fii primul.