العودة إلى المدونة

cron مقابل مؤقتات systemd: أيهما تستخدم؟

11 سبتمبر 2026

على توزيعة حديثة، استخدم مؤقت systemd لأي عمل تملكه، وأبقِ cron للأسطر الواحدة للمستخدم وللخوادم التي لم تُنشئها بنفسك. المؤقتات تسجّل كل جولة في السجل، وتستطيع تعويض الجداول الفائتة أثناء إطفاء الجهاز، وتعتمد على ملفات الوحدات نفسها كبقية النظام. يفوز cron في الإيجاز — سطر crontab -e واحد يغلب ملفي وحدات — وهو ما يزال المجدول الوحيد المضمون الوجود في الحاويات المصغرة وأجهزة Unix الغريبة. العيب: cron يفشل بصمت. إذا أخطأ عملك في الثالثة فجرًا، يرسل cron بريدًا لصندوق محلي لا أحد يقرأ، بينما يمنحك المؤقت journalctl -u mytimer.service بالناتج الكامل. أدناه: الفروق الحقيقية، واختبار كل منهما، ولماذا قد لا ينطلق مؤقت، وجدول قرار.

ما الفرق بين cron ومؤقت systemd؟

cron عفريت يقرأ جدول أسطر — خمسة حقول زمنية وأمر — ويشغّل كل أمر حين يطابق الساعة. ذلك هو النموذج كله. لا مفهوم عن “العمل” ككائن: لا وحدة، لا حالة، لا اعتمادات، ولا قيد سجل خاص.

مؤقت systemd ملف وحدة (foo.timer) يطلق ملف وحدة آخر (foo.service) حين يطابق جدوله. العمل كائن من الدرجة الأولى له start وstatus وسجلات وتتبع أعطاب كأي خدمة. والجدولة إما تقويمية (على طراز cron) أو رتيبة (OnBootSec=15min التي لا يلتبس عليها تغير الساعة).

النتائج العملية:

  • التسجيل: تسجل المؤقتات stdout/stderr في السجل لكل وحدة؛ وcron في أحسن الأحوال يرسل بريدًا للمستخدم المحلي.
  • الجولات الفائتة: مؤقت بـ Persistent=true يعمل مرة عند الإقلاع إذا فات جدوله؛ وcron يتخطى ببساطة.
  • الاعتمادات: يمكن للمؤقتات انتظار network-online.target أو نقاط التركيب؛ وcron يطلب منك كتابة منطق إعادة المحاولة في السكربت بنفسك.
  • الصياغة: cron سطر واحد؛ والمؤقت ملفان. تلك هي كل تكلفة الانتقال.

أي صياغة جدولة أسهل — crontab أم OnCalendar؟

حقول cron الخمسة هي الحاكمة المدمجة: */15 * * * * كل 15 دقيقة، ومعظم الإداريين يقرؤونها وأعينهم مغمضة. أما OnCalendar= في systemd فأطول نطقًا لكنها أعلى تعبيرًا بلا ريب، وsystemd-analyze calendar يخبرك بالجولات القادمة قبل أن تلتزم — لا يملك cron تجربة جافة مماثلة.

# cron: كل يوم في 03:30
30 3 * * * /usr/local/bin/backup.sh

# systemd: الجدول نفسه، قابل للتحقق قبل الحفظ
systemd-analyze calendar "*-*-* 03:30:00"
# -> Next elapse: Fri 2026-09-11 03:30:00 ...

يتعامل OnCalendar مع أشياء لا يعبر عنها cron بوضوح حقًا: Mon..Fri *-*-* 09..17:00:00 (أيام العمل، ساعات الدوام)، أو *:0/15 مع RandomizedDelaySec=10m ليمنع ألف جهاز من قصف خادم في اللحظة ذاتها.

كيف أختبر مؤقت systemd دون انتظار؟

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

systemctl list-timers --all                 # كل مؤقت، الجولة القادمة + الأخيرة
sudo systemctl start backup.service         # أطلق العمل الآن، الوحدة نفسها
journalctl -u backup.service -f             # راقب ناتجه مباشرة

لاحظ الانقسام: systemctl start backup.timer يسلّح الجدول؛ أما الخدمة فهي العمل. إذا عرض list-timers مؤقتك، وكان systemctl status backup.service أخضر، وأظهر السجل ناتجك، فالسلسلة كلها تعمل.

كيف أشغّل عمل cron يدويًا؟

تعمل أعمال cron ببيئة مقتطعة، ولهذا “يعمل في طرفيتي ويفشل في cron” نوع أدبي من الأخطاء. لإعادة إنتاج cron بأمانة، شغّل الأمر عبر sh بالبيئة نفسها التي سيستخدمها cron:

crontab -l                                  # أكد السطر بالضبط
env -i SHELL=/bin/sh PATH=/usr/bin:/bin sh -c '/usr/local/bin/backup.sh'
grep CRON /var/log/syslog | tail            # هل أطلقه cron أصلًا؟ (Debian/Ubuntu)
journalctl -u cron -n 20                    # الشيء نفسه على توزيعات systemd

سطر env -i هو الاختبار اليدوي الصادق: بيئة عارية بمسار PATH الافتراضي لـ cron. أغلب فشل cron الصامت هو PATH عارية أو % غير مقتبس في الأمر (يعامل cron الـ % كسطر جديد)، وكلاهما يظهر فورًا بهذه الطريقة.

لماذا لا ينطلق مؤقت systemd الخاص بي؟

أربعة أسباب تغطي كل حالة تقريبًا، بترتيب فحصها:

  1. اسم الخدمة والمؤقت لا يتطابقان. يطلق foo.timer الخدمة foo.service — خطأ مطبعي في OnFailure أو وحدة أعيدت تسميتها يعني أن المؤقت “يعمل” في العدم. يعرض systemctl cat foo.timer هدفه بالضبط.
  2. المؤقت عُدّل ولم يُعاد تحميله. بعد تغيير ملف وحدة: sudo systemctl daemon-reload && sudo systemctl restart foo.timer. بدونه جدولك الجديد ليس حيًا.
  3. Persistent=true دون دلالات OnCalendar التي تتوقعها — أو أنك تفحص systemctl status foo.timer (يعرض نشطًا دائمًا حتى في الخمول) بدل list-timers.
  4. الخدمة التي يطلقها تفشل فورًا فيبدو المؤقت ميتًا. سيُظهر journalctl -u foo.service --since -1h الانهيار الذي يخفيه list-timers.

وعندما تنظر إلى السجلات فعلًا، تغطي ورقة أوامر journalctl الفلاتر (-u و--since و-f) التي تجعل هذا سريعًا.

cron مقابل مؤقتات systemd: جدول القرار

cronمؤقت systemd
الإعدادسطر crontab واحدملفا وحدة
التسجيلبريد محلي، غالبًا غير مقروءالسجل، لكل وحدة
جولة فائتة (الجهاز مطفأ)تُتخطىتعمل مرة بـ Persistent=true
الاعتمادات/الترتيبلا شيء — اعملها بنفسك في السكربتاعتمادات وحدات كاملة
تأخير عشوائيبنفسك مع $RANDOMRandomizedDelaySec=
اختبار/تجربة الجدوللاsystemd-analyze calendar
موجود في كل مكاننعم — حاويات، BSD، مدمجاتيحتاج systemd (PID 1)
أعمال مستخدم بلا rootcrontab -eوحدات systemd --user

قواعد إبهام: نشر عمل على جهازك الخاص ذي systemd → مؤقت. تذكير شخصي سريع أو جهاز لم تبنه → cron. وأي شيء فيه اعتمادات أو إعادة محاولة أو حاجة لمعرفة هل جرى فعلًا → مؤقت، دائمًا. والنمط الشائع مؤقت يشغّل عمل صيانة — كنسخة احتياطية ليلية بـ rsync — حيث تضمن Persistent=true حدوث النسخة حتى لو كان الجهاز نائمًا في الدقيقة المجدولة، وهو ما لا يقدمه cron ببساطة.

— mrsaynothing

— mrsaynothing

ملاحظات ميدانية في الذكاء الاصطناعي وLinux والاستضافة الذاتية.

ناقش هذا المقال على dev.to dev.to ↗

احصل على الشرح التطبيقي التالي بالبريد

رسالة واحدة لكل مقال. أصلح المشكلة وامضِ.

self-hosted · بلا أطراف ثالثة · إلغاء الاشتراك بنقرة واحدة

ما هذا؟

llama.cpp مقابل Ollama: أيهما تشغّل في 2026؟

أعجبتك هذه الكتابات؟ بناء مثل هذا هو عملي. وظّفني