كيفية (ولماذا) استبدال مهام cron بمؤقتات systemd

كان أحد التغييرات التي أدخلها systemd هو طريقة جديدة لجدولة المهام، مع دقة أكبر من cron. لم تعد بعض توزيعات Linux توفر cron. حان الوقت لإلقاء نظرة على مؤقتات systemd.




لماذا تحل مؤقتات systemd محل cron

يعود تاريخ cron إلى عام 1975، في الإصدار 7 من نظام التشغيل Unix. وسرعان ما أصبحت موثوقيته أداة مفضلة لجدولة المهام لتشغيلها في تواريخ وأوقات محددة. ومن المسلم به أن تركيبته النحوية غريبة إلى حد كبير. وإذا كنت لا تستخدمه بشكل متكرر، فربما تحتاج إلى البحث عن النقاط الدقيقة في كل مرة تريد فيها جدولة مهمة.

في جداول cron، يتم ترقيم الأيام والأشهر بدءًا من واحد. ومع ذلك، يتم ترقيم أيام الأسبوع من صفر إلى ستة، من الأحد إلى السبت. وفي بعض الأنظمة، يعني الرقم سبعة الأحد أيضًا. ولكن على الرغم من غرابة هذا، إلا أنه يعمل.

لقد قدم مدير الخدمة systemd أكثر من مجرد بديل بسيط لمدير التمهيد init. وكان جزء مما قدمه هو بديل حديث لـ cron، في هيئة مؤقتات systemd. توفر هذه المؤقتات مرونة أكبر من تلك التي توفرها cron، ودون الحاجة إلى أداة مساعدة خارجية أخرى. وهي مدمجة مباشرة في جميع توزيعات systemd.


هذا يعني أن المؤقتات تتصرف بنفس الطريقة في جميع تثبيتات systemd. هناك العديد من إصدارات cron والبدائل المشابهة لـ cron. إذا كنت بحاجة إلى توحيد المعايير عبر عدد من أجهزة الكمبيوتر، فإن systemd يجعل حياتك أسهل. ستعمل نفس المؤقتات بنفس الطريقة على جميعها. في الواقع، لم تعد بعض التوزيعات المستندة إلى systemd تقدم cron كجزء من عروضها القياسية.

ليس من المستغرب أن التوزيعات المشتقة من Red Hat بما في ذلك Fedora لا توفر cron، لأن systemd هو القبعة الحمراء المبادرة. لا تتضمن Arch ومشتقاتها cron، ولكن ربما يكون ذلك بسبب توفيرها لتوزيعة بسيطة للغاية بحيث يمكنك ملءها بالتطبيقات التي تناسبها. لا ترى توزيعات أخرى، مثل Solus، الحاجة إلى تضمين cron أيضًا. بالطبع، يمكنك تثبيت cron على أي توزيع تريده، ولكن لا توجد حجة مقنعة للقيام بذلك.


ذات صلة: لماذا لا يزال نظام Linux systemd مثيرًا للانقسام بعد كل هذه السنوات

كيف تعمل مؤقتات systemd

مع مؤقتات systemd، تحتاج إلى إنشاء ملفين. أحدهما هو خدمة الملف. عندما يتم تشغيل الخدمة، فإنها تقوم بتشغيل عمليتك نيابةً عنك. لذا، يحتاج ملف الخدمة إلى معرفة عمليتك المستهدفة.

الملف الثاني الذي تحتاج إلى إنشائه هو مؤقت الملف. يحدد هذا متى يتم تشغيل الخدمة. لذا، يحتاج ملف المؤقت إلى معرفة ملف الخدمة الخاص بك.

يمكن أن تكون المؤقتات في الوقت الحالى أو رتيبيتم تشغيل المؤقتات في الوقت الفعلي من خلال أحداث التقويم. يتم تشغيل المؤقتات الرتيبة بعد فترة زمنية معينة من حدث النظام، مثل التمهيد. تتم إضافة إدخالات السجل إلى مجلة النظام لأحداث المؤقت، والتي يمكن أن تساعد في تصحيح الأخطاء.

يمكنك سرد المؤقتات الموجودة على جهاز الكمبيوتر الخاص بك باستخدام خيار الحالة في الأمر systemctl. يتم إنشاء العديد من مؤقتات النظام تلقائيًا، لذا حتى إذا لم تقم بإنشاء أي مؤقتات، فسوف يكون هناك إخراج لهذا الأمر.


systemctl status "*timer" 
قائمة مؤقتات systemd التي تم تكوينها

يحتوي كل وصف على المعلومات التالية:

  • المؤقت اسم والوصف، إذا تم توفيره.
  • محملة:يعرض حالة التحميل. عادةً ما تتم قراءة المؤقت وتحميله إلى الذاكرة. يتم عرض مسار الدليل إلى ملف المؤقت. نتوقع أن يكون المؤقت “ممكّنًا”، ولكن قد يكون “معطلًا” مؤقتًا إذا اخترنا إيقاف تشغيله. يشير الإعداد المسبق للبائع إلى ما إذا كان المؤقت مضبوطًا على “ممكّن” أو “معطل” عند إنشائه لأول مرة.
  • نشيط:يعرض الحالة النشطة، بما في ذلك التاريخ والوقت الذي تم فيه تنشيط المؤقت. عادةً، تتوقع أن ترى مؤقتًا مدرجًا على أنه “نشط” و”في انتظار” وقت وتاريخ الإطلاق التاليين.
  • حتى:من المربك أن هذا السطر لا ينطبق على المؤقتات. يمكننا تجاهله.
  • مشغل:يظهر اسم العملية التي يتم تشغيلها بواسطة المؤقت.
  • المحفزات:يظهر متى سيتم تشغيل المؤقت التالي، ومتى سيتم تشغيل العملية التالية.
  • المستندات:ترتبط بعض المؤقتات بوثائق. هذا السطر اختياري، ولا يكون موجودًا دائمًا.


نظرًا لأن المؤقتات هي في الواقع خدمات يتم التحكم فيها بالوقت، فيمكننا استخدام الأمر systemctl للتحكم فيها.

إنشاء مؤقت بسيط لنظام systemd

الكلمة المكتوبة هي وسيط ثابت، مما يجعل من الصعب توضيح عملية يتم تشغيلها في وقت محدد. ما سنفعله هو إنشاء نص برمجي سيتم تشغيله بواسطة المؤقت الجديد، وجعله يكتب علامة زمنية في ملف سجل. سيخبرنا ذلك أن خدمتنا تعمل، ومتى تم تشغيلها آخر مرة.

سنستخدم أمر التاريخ لإنشاء الطابع الزمني، وسنعيد توجيهه إلى ملف يسمى “timer.log” في الدليل الرئيسي لدينا.

سنقوم بإنشاء البرنامج النصي في الدليل “/usr/local/bin/”. نحن نستخدم محرر “gedit”، ولكن يمكنك استخدام أي محرر تفضله.

sudo gedit /usr/local/bin/geek-timer.sh  
إنشاء ملف البرنامج النصي geek-timer.sh


انسخ هذه الأسطر إلى محرر النصوص الخاص بك، ثم احفظ الملف باسم “geek-timer.sh”، وأغلق محرر النصوص الخاص بك.

#!/bin/bash

echo "Timer fired: $(date)" >> /home/dave/timer.log

سوف نحتاج إلى جعل البرنامج النصي الخاص بنا قابلاً للتنفيذ.

sudo chmod +x /usr/local/bin/geek-timer.sh 
جعل البرنامج النصي geek-timer-sh قابلاً للتنفيذ

دعونا نتحقق فقط من أن البرنامج النصي الخاص بنا يفعل ما هو المقصود منه.

geek-timer.sh
cat timer.log
تشغيل البرنامج النصي geek-timer.sh والتحقق من كتابته في ملف السجل

يتحقق ذلك من أن البرنامج النصي الخاص بنا يتم تنفيذه كما هو متوقع ويضع علامة زمنية في ملف “timer.log”.

الآن سنقوم بإنشاء ملف خدمة لتحديد الخدمة التي نريد تشغيلها عند تشغيل المؤقت.


sudo gedit /etc/systemd/system/geek-timer.service  
إنشاء ملف geek-timer.service

انسخ هذه الأسطر إلى محرر النصوص الخاص بك، ثم احفظ الملف باسم “/etc/systemd/system/geek-timer.service”، ثم أغلق محرر النصوص الخاص بك.

(Unit)
Description="How-To Geek systemd timer"
Requires=geek-timer.timer

(Service)
Type=simple
ExecStart=/usr/local/bin/geek-timer.sh
User=dave

يحتوي قسم “(Unit)” على سطرين. سطر “Description=” عبارة عن سطر واحد بسيط يوضح الغرض من الخدمة. يشير سطر “Requires=” إلى أن هذه الخدمة تعتمد على ملف المؤقت “geek-timer.timer”. سنقوم بإنشاء هذا الملف بعد ذلك.

يوجد المزيد في قسم “(الخدمة)”. “Type=” هو “بسيط”، مما يعني أن هذه خدمة أساسية. تتضمن الخيارات الأخرى “oneshot”، مما يعني أن الخدمة تعمل مرة واحدة فقط.


يشير السطر “ExecStart=” إلى العملية التي يجب أن تبدأها الخدمة. يشير هذا إلى البرنامج النصي الذي أنشأناه سابقًا.

يحدد السطر “User=” المستخدم الذي يجب أن يقوم بتشغيل الأمر. بدون هذا، سيتم تشغيل العملية بواسطة الجذر.

الآن سنقوم بإنشاء ملف المؤقت. يحدد هذا الملف متى يتم تشغيل الخدمة. من الأفضل استخدام نفس الاسم الأساسي لملفات الخادم والمؤقت، مع امتدادات مختلفة.

sudo gedit /etc/systemd/system/geek-timer.timer 
إنشاء ملف geek-timer.timer

انسخ هذه الأسطر إلى محرر النصوص الخاص بك، ثم احفظ الملف باسم “/etc/systemd/system/geek-timer.timer”، ثم أغلق محرر النصوص الخاص بك.


(Unit)
Description="Timer for the geek-timer.service"

(Timer)
Unit=geek-timer.service
OnBootSec=5min
OnUnitActiveSec=1min

(Install)
WantedBy=timers.target

يحتوي قسم “(Unit)” على سطر نصي “Description=”. يحتوي قسم “(Timer)” على ثلاثة إعدادات. يشير سطر “Unit=” إلى الخدمة التي يجب تشغيلها عند تشغيل هذا المؤقت. يخبر سطر “OnBootSec=” النظام بتشغيل الخدمة بعد خمس دقائق من تشغيل الكمبيوتر. يخبر سطر “OnUnitActiveSec=” المؤقت بتشغيل الخدمة بعد دقيقة واحدة من تنشيطها آخر مرة.

بمعنى آخر، بعد خمس دقائق من تشغيل الكمبيوتر، سيتم تشغيل الخدمة. ثم تتكرر الخدمة بفاصل زمني قدره دقيقة واحدة.

في قسم “(التثبيت)”، قمنا بتضمين سطر “WantedBy=” الذي يحدد “timers.target”. “timers.target” هي وحدة هدف خاصة تقوم بإعداد جميع وحدات المؤقت النشطة بعد التمهيد، وهي مناسبة لجميع مؤقتات systemd الأساسية.

يمكننا استخدام أمر systemctl status لإلقاء نظرة على المؤقت الجديد لدينا.


systemctl status geek-timer.service 
استخدام systemctl status لإظهار حالة المؤقت الجديد لدينا

لم يتم الإبلاغ عن أي أخطاء، وهو أمر جيد. إنه غير نشط لأننا لم نبدأ الخدمة. حتى إذا أعدنا التشغيل الآن، فلن يتم تمكين الخدمة والمؤقت. فلنبدأ ونقوم بتمكين المؤقت.

sudo systemctl enable geek-timer.timer
sudo systemctl start geek-timer.timer
تمكين وبدء تشغيل المؤقت الجديد باستخدام الأمر systemctl

لقد قمت بإعادة تشغيل جهاز الكمبيوتر التجريبي لمعرفة ما إذا كان قد تم احترام فترة السماح التي تبلغ خمس دقائق بعد بدء التشغيل، وتحققت من حالته مرة أخرى.


systemctl status geek-timer.service 
حالة المؤقت قبل انتهاء فترة الخمس دقائق بعد التمهيد

يُظهر هذا أن جهاز الكمبيوتر تم تشغيله في الساعة 12:18، وسيتم تشغيل المؤقت لدينا في الساعة 12:23. يتم التعامل مع خيار الخمس دقائق المطلوبة بعد التشغيل بشكل صحيح. انتظرت حتى انقضاء الخمس دقائق ثم قمت بتشغيل نفس الأمر بسرعة.

systemctl status geek-timer.service 
حالة المؤقت بمجرد وصوله إلى مرحلة التكرار كل دقيقة

يمكننا أن نرى أن وقت التشغيل قد انتقل بدقيقة واحدة من 12:23 إلى 12:24. وهذا يعني أننا الآن في مرحلة “تكرار كل دقيقة” في عداد الوقت الخاص بنا.

عند فحص ملف السجل الخاص بنا بعد بضع دقائق، يظهر وقت التشغيل الأولي وهو 12:23، ثم تحدث عمليات الإطلاق اللاحقة في عن دقيقة واحدة فقط.


cat timer.log

محتويات ملف سجل المؤقت بعد حوالي عشر دقائق من التشغيل

ذات صلة: كيفية إدراج خدمات Linux باستخدام systemctl

ضبط التوقيتات بشكل دقيق

أوقات تشغيل الأحداث المتكررة غير واضحة بعض الشيء. لهذا السبب قلت إن الأحداث في ملف السجل هي عن يتم تشغيل المؤقتات المجدولة للتشغيل في نفس الوقت على وجه التحديد بشكل متدرج. عادةً، بالنسبة للمهام مثل بدء النسخ الاحتياطي أو أنشطة تنظيف النظام الأخرى، يكون هذا دقيقًا بدرجة كافية.

إذا كنت بحاجة إلى دقة أكثر دقة، فيمكنك استخدام توقيت الميكروثانية. يؤدي إضافة هذا السطر إلى قسم “(المؤقت)” في ملف المؤقت إلى ضبط النظام لاستخدام دقة ميكروثانية واحدة.


AccuracySec=1us 

هذه هي إعدادات الدقة التي يمكنك استخدامها، وكيفية الرجوع إليها.

  • ميكروثانية:us, µs msec, ms
  • ثواني:ثواني، ثانية، ثانية، ثانية
  • دقائق: دقائق، دقيقة، دقيقة، دقيقة
  • ساعات:ساعات، ساعة، ساعة، ساعة
  • أيام: أيام، يوم، د
  • اسابيع:أسابيع، أسبوع، و
  • شهور: أشهر، شهر، م
  • سنين: سنوات، سنة، سنة

يتم تحقيق تشغيل المؤقت في وقت وتاريخ معينين باستخدام إعداد “OnCalendar”. يتم إدخال هذا الإعداد في قسم “(المؤقت)” من ملف المؤقت. والتنسيق العام هو:

OnCalendar=DayOfTheWeek YYYY-MM-DD HH:MM:SS 

إن DayOfTheWeek اختياري. يمكن استبدال أي من القيم الأخرى بعلامة النجمة “*” لتعني “كل”، مثل كل دقيقة أو كل ساعة. يمكنك استخدام الأسماء أو الأرقام للأيام والأشهر، وقوائم مفصولة بفواصل لتمثيل اختيارات القيم. يتم الإشارة إلى نطاقات القيم باستخدام نقطتين “..” لفصل بداية وقيم النطاق.


سيؤدي هذا إلى ضبط مؤقت ليتم تشغيله في الساعة 01:15 في أول جمعة من كل شهر.

OnCalendar=Fri *-*-1..7 01:15:00 

سيتم تنفيذ هذه العملية في الساعة 19:00 كل يوم.

OnCalendar=*-*-* 19:00:00 

يمكن أن يكون للمؤقت أكثر من وقت تشغيل محدد. وهذا من شأنه أن يؤدي إلى تشغيل عملية في وقت مختلف في أيام العمل عن عطلة نهاية الأسبوع.

OnCalendar=Mon..Fri 23:00:00
OnCalendar=Sat,Sun 19:00:00

ال صفحة دليل الوقت في systemd وصف كامل لتنسيقات الوقت والعديد من النصائح والحيل المفيدة.

مرونة كبيرة وسهولة في الاستخدام

يكمن قدر كبير من مرونة مؤقتات systemd في الطريقة التي يمكنك بها التعامل مع الأحداث غير العادية في التقويم. على سبيل المثال، لتعيين مؤقت ليتم تشغيله في الساعة 15:00 في جميع الأيام باستثناء أيام الجمعة، يمكنك استخدام هذا التنسيق:

Mon..Thu,Sat,Sun *-*-* 15:00:00 

من خلال الجمع بين القوائم والنطاقات المنفصلة بفواصل، ستجد أنه من السهل إنشاء مشغلات في الوقت الفعلي لجميع أنواع المتطلبات المعقدة.

بمجرد أن تتوصل إلى فكرة إنشاء خدمة لتشغيل عمليتك، وملف مؤقت للتحكم في تشغيل الخدمة، تكون قد قطعت 90% من الطريق لفهم مؤقتات systemd. وتتمثل النسبة المتبقية البالغة 10% في استيعاب القوة الرائعة لأحداث التقويم.


ذات صلة: كيفية تشغيل برنامج Linux عند بدء التشغيل باستخدام systemd

أضف تعليق