ממיר cron ל-timer של systemd

מדביקים לוח זמנים של cron או שורת crontab שלמה. מקבלים מה היא אומרת, מתי היא תרוץ, ו-service ו-timer של systemd שעושים אותו דבר, עם הפקודות שמתקינות אותם.

חמישה שדות (דקה שעה יום חודש יום-בשבוע) או מאקרו כמו @daily. שורה שלמה מ-crontab -l מפוצלת אוטומטית.
כמו ב-crontab. פקודה עם pipe, הפניות, מירכאות או $ רצה דרך ‎/bin/sh -c, כמו ש-cron מריץ אותה.
שני הקבצים מקבלים את השם הזה: ‎<name>.service ו-‎<name>.timer.
הבעלים של ה-crontab. ריק: רץ כ-root, כמו ‎/etc/crontab עם root.
אופציונלי, למשל 5min: מפזר את ההפעלה על פני החלון כדי ששרתים לא יתחילו יחד.
אם השרת היה כבוי בזמן המתוזמן, המשימה רצה פעם אחת באתחול הבא. ‏cron (בלי anacron) מדלג עליה.
כבוי כברירת מחדל, כי cron לא מריץ משימות ב-sandbox. כשהוא פעיל: ‎/usr, ‏‎/boot ו-‎/etc לקריאה בלבד עבור המשימה.

מה זה אומר

בשעה 02:30.

אותו לוח זמנים בפורמט לוח השנה של systemd:

  • OnCalendar=*-*-* 02:30:00

חמש ההרצות הבאות

השרת קורא את OnCalendar=‎ באזור הזמן שלו (timedatectl). בחרו UTC אם השרת עובד ב-UTC.

ה-service וה-timer שלכם

backup-nightly.service
# backup-nightly.service: Nightly backup
# Generated by @anaroq/linux 1.0.0 (ANAROQ).
[Unit]
Description=Nightly backup

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup --quiet
Restart=no
backup-nightly.timer
# backup-nightly.timer: Nightly backup
# Generated by @anaroq/linux 1.0.0 (ANAROQ).
# From cron "30 2 * * *": At 02:30.
[Unit]
Description=Nightly backup

[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true

[Install]
WantedBy=timers.target

העברה לסוכן

משימה ב-Markdown לסוכן קוד: הקבצים, הממצאים, המגבלות וגבולות בטיחות קבועים. ערכים שנראים כמו סודות ממוסכים. היא נבנית בעמוד הזה ולא נשלחת לשום מקום.

איך עובדת ההעברה לסוכן

התקנה והפעלה של ה-timer

מריצים את אלה בשרת, בתיקייה שבה שמרתם את שני הקבצים, ואז מוחקים את השורה מה-crontab כדי שהמשימה לא תרוץ פעמיים.

install-commands.txt
sudo install -m 0644 backup-nightly.service /etc/systemd/system/backup-nightly.service
sudo install -m 0644 backup-nightly.timer /etc/systemd/system/backup-nightly.timer
sudo systemd-analyze verify /etc/systemd/system/backup-nightly.service /etc/systemd/system/backup-nightly.timer
sudo systemctl daemon-reload
sudo systemctl enable --now backup-nightly.timer
systemctl list-timers backup-nightly.timer
journalctl -u backup-nightly.service -f

מה משתנה כש-cron הופך ל-timer

  • הפלט נכתב ליומן (journalctl -u <name>.service), לא נשלח במייל מ-cron.
  • ‏systemd מריץ את המשימה עם הסביבה שלו, לא עם ה-PATH הקצר של cron. השתמשו בנתיבים מוחלטים, או הגדירו את המשתנים ב-service.
  • ‏timer לא מפעיל את המשימה שוב כל עוד ההרצה הקודמת עדיין רצה; ‏cron היה מפעיל עותק שני.
  • עם Persistent=true, הרצה שהוחמצה כשהשרת היה כבוי מתבצעת באתחול הבא.

צריכים שירות שרץ כל הזמן? כתבו אותו במחולל שירות systemd

מה הכלי עושה

הכלי קורא לוח זמנים של cron כמו ש-cron קורא אותו, אומר במילים מתי הוא רץ, מציג את חמש ההרצות הבאות מתאריך שתבחרו, וכותב service ו-timer של systemd שמריצים את אותה פקודה באותו לוח זמנים.

איך זה עובד

  1. לוח הזמנים נקרא על ידי ‎@anaroq/linux, המנוע של שאר כלי ה-Linux שלנו, עם הטווחים, הצעדים, הרשימות, שמות החודשים והימים ומאקרו @ של cron, ונדחה עם השדה והסיבה כש-cron לא היה מקבל אותו.
  2. כל שדה הופך לחלק מביטוי לוח שנה של systemd. כששני שדות היום מוגבלים, ‏cron רץ בכל אחד מהם, ולכן ה-timer מקבל OnCalendar=‎ לכל אחד; כשאחד מהם מתחיל ב-*, שניהם צריכים להתאים, כמו ב-cron.
  3. הפקודה רצה ישירות כשהיא לא צריכה shell, ודרך ‎/bin/sh -c בכל מקרה אחר. לכלל ה-% של cron אין מקבילה ב-systemd והוא נדחה; ‏\% הופך ל-%.
  4. ההרצות הבאות מחושבות בדפדפן הזה, מהתאריך ומאזור הזמן שתבחרו; שום דבר לא נשלח. כל פלט golden עובר systemd-analyze verify ו-systemd-analyze calendar בבדיקות שלנו.

לוחות זמנים נפוצים

cronמשמעותOnCalendar=
*/15 * * * *כל 15 דקות.*-*-* *:00/15:00
0 * * * *בדקה 0 של כל שעה.*-*-* *:00:00
0 3 * * *בשעה 03:00.*-*-* 03:00:00
30 2 * * 0בשעה 02:30 בימי ראשון.Sun *-*-* 02:30:00
0 9-17 * * mon-friבדקה 0 של כל שעה, בשעות 09–17 בימי שני–שישי.Mon..Fri *-*-* 09..17:00:00
0 0 1 * *בשעה 00:00 ביום 1 בחודש.*-*-01 00:00:00
0 4 1-7 * 1בשעה 04:00 בימים 1–7 בחודש או בימי שני.Mon *-*-* 04:00:00*-*-01..07 04:00:00
@rebootפעם אחת, בכל הפעלה של השרת.OnBootSec=1min

דוגמה

גיבוי לילי ב-02:30 הופך ל-service ול-timer האלה:

30 2 * * * /usr/local/bin/backup --quiet

בשעה 02:30.

backup-nightly.service
# backup-nightly.service: Nightly backup
# Generated by @anaroq/linux 1.0.0 (ANAROQ).
[Unit]
Description=Nightly backup

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup --quiet
Restart=no
backup-nightly.timer
# backup-nightly.timer: Nightly backup
# Generated by @anaroq/linux 1.0.0 (ANAROQ).
# From cron "30 2 * * *": At 02:30.
[Unit]
Description=Nightly backup

[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true

[Install]
WantedBy=timers.target

הפקודות שמתקינות אותם

install-commands.txt
sudo install -m 0644 backup-nightly.service /etc/systemd/system/backup-nightly.service
sudo install -m 0644 backup-nightly.timer /etc/systemd/system/backup-nightly.timer
sudo systemd-analyze verify /etc/systemd/system/backup-nightly.service /etc/systemd/system/backup-nightly.timer
sudo systemctl daemon-reload
sudo systemctl enable --now backup-nightly.timer
systemctl list-timers backup-nightly.timer
journalctl -u backup-nightly.service -f

מגבלות

  • הרחבות כמו L, ‏W, ‏# ו-? (מ-Quartz או מתזמנים אחרים) אינן תחביר של cron ונדחות.
  • השירות רץ כ-root אלא אם תציינו את המשתמש של ה-crontab. הסביבה של crontab של משתמש (שורות MAILTO, ‏SHELL, ‏PATH) לא מומרת.
  • ההרצות הבאות מחושבות לפי אזור הזמן שבחרתם. בימים שבהם השעון זז, שעה שלא קיימת מדולגת, ומימושי cron שונים מתנהגים שם אחרת.
  • ה-timer מחליף את שורת ה-crontab; מחקו את השורה בעצמכם, אחרת המשימה תרוץ פעמיים.

צריכים שירות שרץ כל הזמן? כתבו אותו במחולל שירות systemd

מקורות

  1. systemd.service(5)
  2. systemd.exec(5)
  3. systemd.unit(5)
  4. systemd.timer(5)
  5. systemd-analyze(1)
  6. systemd.time(7): calendar events
  7. crontab(5) (cronie)

עודכן

הצעד הבא

מחולל שירות systemd

כלי ציבורי חינמי של אנרוק, חברה שבונה תשתיות מחשוב. מה אנרוק בונה