← شروع آموزش

WIUNIX ACADEMY

زمان‌بندی با systemd timer؛ نوبت ازدست‌رفته و اجرای تکراری رو مدیریت کن

صفحهٔ 3 از 4؛ قبل از ادامه، مراحل قبلی و چیزهایی رو که لازم داری مرور کن.

آموزش متناسب با محیط تو

کجا اجرا می‌کنی؟

سیستم‌عامل و نسخهٔ سرورت رو انتخاب کن تا مراحل، دستورها و راه‌حل‌های همون محیط رو ببینی.

Debian 13بررسی‌شده با مستندات رسمی ·

آموزش متناسب با مقادیر تو

تنظیمات این آموزش

مقادیر نمونه رو با مشخصات سرورت عوض کن تا متن و دستورها با هم تغییر کنن. رمز، کلید خصوصی و توکن اینجا وارد نکن. مقدارها فقط توی همین زبانه می‌مونن و به سرور یا لینک اشتراک‌گذاری فرستاده نمی‌شن. قبل از اجرا، DNS، گواهی‌ها و تنظیمات دسترسی شبکه رو روی سرورت بررسی کن.

اگر آی‌پی، دامنه یا پورت‌های نمونه با سرورت فرق دارن، بخش تنظیمات پایین رو باز کن. مقدارها رو عوض کن و «اعمال در آموزش» رو بزن؛ بعد دستورهای تازه رو کپی کن.

تنظیم مقادیر برای محیط من3 مقدار قابل‌تغییر
07

قدم بعدی

اگر timer شروع کرد ولی کار تموم نشد

نتیجهٔ سرویس و لاگ حوالی همان نوبت رو بخون. فایل مفقود، اشکال نحو، تمام‌شدن مهلت، ردشدن دسترسی پوشهٔ داده یا فایل نهایی خراب، خطای برنامه است و با درست‌کردن عبارت تقویمی رفع نمی‌شه. قبل از پاک‌کردن وضعیت failed، پیام‌های اولین شکست رو نگه دار.

فایل این تمرین نتیجهٔ بررسی بکاپ نیست. برای نمونه، خود فایل کوچک و تاریخش رو ببین. برای کار واقعی، قبل از تکرار سراغ روش اعتبارسنجی و بازیابی خودش برو. لاگ نمی‌تونه انجام کاری رو ثابت کنه که برنامه ثبت نهایی نکرده.

bash

ترمینال میزبان آزمایشی با دسترسی مجاز

systemctl status 'academy-daily-marker.service' --no-pager
systemctl show 'academy-daily-marker.service' -p Result -p ExecMainCode -p ExecMainStatus -p TimeoutStartUSec
sudo journalctl -u 'academy-daily-marker.service' -u 'academy-daily-marker.timer' --since '-1 hour' --no-pager -n 100
sudo ls -la '/var/lib/academy-daily-marker/'
از کجا بفهمم درست انجام شده؟

شکست به کد خروج، مهلت، مسیر یا پیام سیاست دسترسی وصل شده. کد خروج غیرصفر همچنان اجرای ناموفق حساب می‌شه.

08

قدم بعدی

محدودیت میزبان رو با مشکل timer قاطی نکن

ردشدن دسترسی ممکنه از مجوز معمولی فایل یا پروفایل فعال AppArmor بیاد و ربطی به ساعت اجرا نداشته باشه. پیام کرنل رو با همین کار و زمان شکست تطبیق بده. برای عبور از تمرین، اجرای سیاست امنیتی رو خاموش نکن.

اسکریپت باید متعلق به root و برای هویت موقت قابل‌خوندن باشه. قبل از دست‌کاری محدودیت‌های سرویس، نبودن مفسر یا دسترس‌ناپذیربودن مسیر رو بررسی کن. حتی با فایل timer یکسان، سیاست بسته و پروفایل محلی می‌تونه بین میزبان‌ها فرق داشته باشه.

bash

ترمینال میزبان آزمایشی با دسترسی مجاز

sudo journalctl -k --since '-15 min' --no-pager -n 100
sudo stat -c '%U %G %a %n' '/usr/local/libexec/academy-daily-marker.sh' '/etc/systemd/system/academy-daily-marker.service'
از کجا بفهمم درست انجام شده؟

خطای مجوز یا سیاست میزبان جداگانه شناسایی شده و اجرای سیاست امنیتی تغییری نکرده.

09

قدم بعدی

نوبت‌های بعدی رو متوقف کن؛ اجرای فعلی رو هم ببین

اگر کار شکست خورده یا باید زمان‌بندی رو عوض کنی، اول timer رو متوقف و غیرفعال کن. توقف timer سرویسی رو که از قبل در حال اجراست متوقف نمی‌کنه. وضعیت سرویس رو جدا ببین و اگر ادامه‌دادنش بی‌خطره، صبر کن تموم بشه؛ غیرفعال‌شدن زمان‌بندی به معنی لغو کار نیست.

کار کوچک این تمرین رو در صورت نیاز می‌شه متوقف کرد، اما بکاپ یا مهاجرت دادهٔ واقعی روش توقف خودش رو لازم داره. دادهٔ نیمه‌کاره و لاگ رو نگه دار. پردازش نامرتبط رو فقط به خاطر شباهت اسمش به این نمونه متوقف نکن.

bash

ترمینال میزبان آزمایشی با دسترسی مجاز

sudo systemctl disable --now 'academy-daily-marker.timer' || exit 1
systemctl show 'academy-daily-marker.timer' -p ActiveState -p SubState
systemctl show 'academy-daily-marker.service' -p ActiveState -p SubState
sudo journalctl -u 'academy-daily-marker.service' --since '-30 min' --no-pager -n 60
از کجا بفهمم درست انجام شده؟

timer غیرفعال و متوقف شده و می‌دونی سرویس مستقل از اون هنوز در حال اجراست یا تموم شده.

10

قدم بعدی

بعد از رفع علت، دوباره امتحان کن

در همین نمونه، اشکال فایل یا سیاست دسترسی رو رفع کن، فایل‌ها رو دوباره بررسی کن و از راه سرویس تلاش تازه انجام بده. پاک‌کردن وضعیت failed فقط شکست ثبت‌شده و شمارندهٔ محدودیت شروع systemd رو پاک می‌کنه؛ اسکریپت رو تعمیر یا کار نیمه‌کاره رو برنمی‌گردونه.

قبل از فعال‌کردن دوبارهٔ timer، نتیجهٔ تازه رو ببین. timer تقویمیِ Persistent ممکنه با فعال‌شدن یک نوبت جبرانی هم درخواست کنه. فایل روزانه باعث می‌شه تکرار کار امروز بی‌ضرر باشه؛ برای بازیابی خودکارِ برنامهٔ واقعی هم به رفتار مشابه نیاز داری.

bash

ترمینال میزبان آزمایشی با دسترسی مجاز

sudo systemctl reset-failed 'academy-daily-marker.service' || exit 1
sudo systemctl start 'academy-daily-marker.service' || exit 1
sudo systemctl show 'academy-daily-marker.service' -p Result -p ExecMainStatus
sudo journalctl -u 'academy-daily-marker.service' --since '-10 min' --no-pager -n 60
sudo systemctl enable --now 'academy-daily-marker.timer' || exit 1
systemctl is-enabled --quiet 'academy-daily-marker.timer' || exit 1
systemctl is-active --quiet 'academy-daily-marker.timer' || exit 1
systemctl list-timers --all 'academy-daily-marker.timer'
از کجا بفهمم درست انجام شده؟

اجرای تازه موفق شده یا انجام‌شدن کار امروز رو تأیید کرده؛ فقط بعد از اون timer دوباره منتظر است.

11

قدم بعدی

اختیاری: به‌جای ساعت روز، از پایان کار فاصله بگیر

اگر خواسته‌ات «سی دقیقه بعد از پایان کار» است، این جایگزین رو انتخاب کن. timer رو متوقف کن و قبل از ویرایش صبر کن سرویس غیرفعال بشه. یک نسخه از فایل تقویمی همین تمرین نگه می‌داریم و تمام محتوای فایل رو با پنل بعدی عوض می‌کنیم؛ تنظیمات تازه رو ته تنظیمات تقویمی اضافه نکن.

اگر فایل پشتیبان از قبل وجود داشته باشه، کپی متوقف می‌شه. این تغییر فقط برای نمونهٔ همین آموزش است و اجازهٔ جایگزینی timer شخص یا کار دیگری نیست. اگر به این جایگزین نیاز نداری، می‌تونی مستقیم سراغ معیارهای پایان راهنما بری.

bash

ترمینال میزبان آزمایشی با دسترسی مجاز

sudo systemctl disable --now 'academy-daily-marker.timer' || exit 1
test "$(systemctl show -p ActiveState --value 'academy-daily-marker.service')" = inactive || exit 1
sudo test ! -e '/etc/systemd/system/academy-daily-marker.timer.calendar-backup' || exit 1
sudo cp -p -- '/etc/systemd/system/academy-daily-marker.timer' '/etc/systemd/system/academy-daily-marker.timer.calendar-backup' || exit 1
sudoedit '/etc/systemd/system/academy-daily-marker.timer' || exit 1
از کجا بفهمم درست انجام شده؟

timer متوقف شده، سرویس تموم شده و قبل از ویرایش، نسخهٔ همان فایل تقویمی نگه داشته شده.

فاصله رو از پایان اجرا حساب کنیم

گزینهٔ OnBootSec اولین شروع رو برای پنج دقیقه بعد از بوت می‌ذاره؛ اگر موقع شروع timer این زمان گذشته باشه، ممکنه بلافاصله تحریک بشه. بعد، OnUnitInactiveSec سی دقیقه رو از غیرفعال‌شدن سرویس حساب می‌کنه. این با OnUnitActiveSec فرق داره که مبدأش شروع فعال‌سازی است.

اینجا نه OnCalendar داریم و نه Persistent؛ لیست فاصله‌های ازدست‌رفته در خاموشی بازیابی نمی‌شه. ساعت یکنواخت هم معمولاً هنگام suspend جلو نمی‌ره. اسکریپت هنوز فقط یک فایل برای هر روز UTC می‌سازه، پس نوبت‌های بیشتر، رفتار زمان‌بندی رو نشون می‌دن و کار تجاری تکراری تولید نمی‌کنن.

ini · /etc/systemd/system/academy-daily-marker.timer

جایگزین اختیاریِ کل فایل؛ در ترمینال اجرا نکن

[Unit]
Description=Academy completion-relative schedule

[Timer]
OnBootSec=5min
OnUnitInactiveSec=30min
AccuracySec=1s
Unit=academy-daily-marker.service

[Install]
WantedBy=timers.target
همهٔ آموزش‌های آکادمی ↗