WIUNIX ACADEMY
زمانبندی با systemd timer؛ نوبت ازدسترفته و اجرای تکراری رو مدیریت کن
صفحهٔ 3 از 4؛ قبل از ادامه، مراحل قبلی و چیزهایی رو که لازم داری مرور کن.
آموزش متناسب با محیط تو
کجا اجرا میکنی؟
سیستمعامل و نسخهٔ سرورت رو انتخاب کن تا مراحل، دستورها و راهحلهای همون محیط رو ببینی.
آموزش متناسب با مقادیر تو
تنظیمات این آموزش
مقادیر نمونه رو با مشخصات سرورت عوض کن تا متن و دستورها با هم تغییر کنن. رمز، کلید خصوصی و توکن اینجا وارد نکن. مقدارها فقط توی همین زبانه میمونن و به سرور یا لینک اشتراکگذاری فرستاده نمیشن. قبل از اجرا، DNS، گواهیها و تنظیمات دسترسی شبکه رو روی سرورت بررسی کن.
اگر آیپی، دامنه یا پورتهای نمونه با سرورت فرق دارن، بخش تنظیمات پایین رو باز کن. مقدارها رو عوض کن و «اعمال در آموزش» رو بزن؛ بعد دستورهای تازه رو کپی کن.
تنظیم مقادیر برای محیط من3 مقدار قابلتغییر
قدم بعدی
اگر timer شروع کرد ولی کار تموم نشد
نتیجهٔ سرویس و لاگ حوالی همان نوبت رو بخون. فایل مفقود، اشکال نحو، تمامشدن مهلت، ردشدن دسترسی پوشهٔ داده یا فایل نهایی خراب، خطای برنامه است و با درستکردن عبارت تقویمی رفع نمیشه. قبل از پاککردن وضعیت failed، پیامهای اولین شکست رو نگه دار.
فایل این تمرین نتیجهٔ بررسی بکاپ نیست. برای نمونه، خود فایل کوچک و تاریخش رو ببین. برای کار واقعی، قبل از تکرار سراغ روش اعتبارسنجی و بازیابی خودش برو. لاگ نمیتونه انجام کاری رو ثابت کنه که برنامه ثبت نهایی نکرده.
ترمینال میزبان آزمایشی با دسترسی مجاز
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/'شکست به کد خروج، مهلت، مسیر یا پیام سیاست دسترسی وصل شده. کد خروج غیرصفر همچنان اجرای ناموفق حساب میشه.
قدم بعدی
شواهد SELinux رو ببین؛ اجرای سیاست رو خاموش نکن
پیام AVC رو با همین سرویس و زمان شکست تطبیق بده و برچسب و مجوز معمولی اسکریپت رو ببین. پنل پایین فقط نشون میده چه برچسبهایی ممکنه اصلاح بشن؛ خودش برچسبی رو تغییر نمیده. قانون مجوز کلی تولید نکن و حالت permissive نذار. خالیبودن خروجی audit هم مشکل سیاست رو رد نمیکنه.
اگر اسکریپت بازیابیشده یا سفارشی برچسب اشتباه داره، قبل از اصلاح با سیاست file-context نصبشدهٔ همین توزیع تطبیقش بده. DynamicUser نه SELinux رو دور میزنه و نه اجازهٔ مسیرهای نامرتبط رو میده.
ترمینال میزبان آزمایشی با دسترسی مجاز
getenforce
sudo ausearch -m AVC,USER_AVC -ts recent
ls -lZ '/usr/local/libexec/academy-daily-marker.sh'
sudo restorecon -n -v '/usr/local/libexec/academy-daily-marker.sh'ردشدن احتمالی دسترسی به شواهد مشخص وصل شده؛ برچسب و اجرای سیاست تغییر نکرده.
قدم بعدی
نوبتهای بعدی رو متوقف کن؛ اجرای فعلی رو هم ببین
اگر کار شکست خورده یا باید زمانبندی رو عوض کنی، اول timer رو متوقف و غیرفعال کن. توقف timer سرویسی رو که از قبل در حال اجراست متوقف نمیکنه. وضعیت سرویس رو جدا ببین و اگر ادامهدادنش بیخطره، صبر کن تموم بشه؛ غیرفعالشدن زمانبندی به معنی لغو کار نیست.
کار کوچک این تمرین رو در صورت نیاز میشه متوقف کرد، اما بکاپ یا مهاجرت دادهٔ واقعی روش توقف خودش رو لازم داره. دادهٔ نیمهکاره و لاگ رو نگه دار. پردازش نامرتبط رو فقط به خاطر شباهت اسمش به این نمونه متوقف نکن.
ترمینال میزبان آزمایشی با دسترسی مجاز
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 غیرفعال و متوقف شده و میدونی سرویس مستقل از اون هنوز در حال اجراست یا تموم شده.
قدم بعدی
بعد از رفع علت، دوباره امتحان کن
در همین نمونه، اشکال فایل یا سیاست دسترسی رو رفع کن، فایلها رو دوباره بررسی کن و از راه سرویس تلاش تازه انجام بده. پاککردن وضعیت failed فقط شکست ثبتشده و شمارندهٔ محدودیت شروع systemd رو پاک میکنه؛ اسکریپت رو تعمیر یا کار نیمهکاره رو برنمیگردونه.
قبل از فعالکردن دوبارهٔ timer، نتیجهٔ تازه رو ببین. timer تقویمیِ Persistent ممکنه با فعالشدن یک نوبت جبرانی هم درخواست کنه. فایل روزانه باعث میشه تکرار کار امروز بیضرر باشه؛ برای بازیابی خودکارِ برنامهٔ واقعی هم به رفتار مشابه نیاز داری.
ترمینال میزبان آزمایشی با دسترسی مجاز
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 دوباره منتظر است.
قدم بعدی
اختیاری: بهجای ساعت روز، از پایان کار فاصله بگیر
اگر خواستهات «سی دقیقه بعد از پایان کار» است، این جایگزین رو انتخاب کن. timer رو متوقف کن و قبل از ویرایش صبر کن سرویس غیرفعال بشه. یک نسخه از فایل تقویمی همین تمرین نگه میداریم و تمام محتوای فایل رو با پنل بعدی عوض میکنیم؛ تنظیمات تازه رو ته تنظیمات تقویمی اضافه نکن.
اگر فایل پشتیبان از قبل وجود داشته باشه، کپی متوقف میشه. این تغییر فقط برای نمونهٔ همین آموزش است و اجازهٔ جایگزینی timer شخص یا کار دیگری نیست. اگر به این جایگزین نیاز نداری، میتونی مستقیم سراغ معیارهای پایان راهنما بری.
ترمینال میزبان آزمایشی با دسترسی مجاز
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 میسازه، پس نوبتهای بیشتر، رفتار زمانبندی رو نشون میدن و کار تجاری تکراری تولید نمیکنن.
جایگزین اختیاریِ کل فایل؛ در ترمینال اجرا نکن
[Unit]
Description=Academy completion-relative schedule
[Timer]
OnBootSec=5min
OnUnitInactiveSec=30min
AccuracySec=1s
Unit=academy-daily-marker.service
[Install]
WantedBy=timers.target