على توزيعة حديثة، استخدم مؤقت 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 الخاص بي؟
أربعة أسباب تغطي كل حالة تقريبًا، بترتيب فحصها:
- اسم الخدمة والمؤقت لا يتطابقان. يطلق
foo.timerالخدمةfoo.service— خطأ مطبعي فيOnFailureأو وحدة أعيدت تسميتها يعني أن المؤقت “يعمل” في العدم. يعرضsystemctl cat foo.timerهدفه بالضبط. - المؤقت عُدّل ولم يُعاد تحميله. بعد تغيير ملف وحدة:
sudo systemctl daemon-reload && sudo systemctl restart foo.timer. بدونه جدولك الجديد ليس حيًا. Persistent=trueدون دلالاتOnCalendarالتي تتوقعها — أو أنك تفحصsystemctl status foo.timer(يعرض نشطًا دائمًا حتى في الخمول) بدلlist-timers.- الخدمة التي يطلقها تفشل فورًا فيبدو المؤقت ميتًا. سيُظهر
journalctl -u foo.service --since -1hالانهيار الذي يخفيهlist-timers.
وعندما تنظر إلى السجلات فعلًا، تغطي ورقة أوامر journalctl الفلاتر (-u و--since و-f) التي تجعل هذا سريعًا.
cron مقابل مؤقتات systemd: جدول القرار
| cron | مؤقت systemd | |
|---|---|---|
| الإعداد | سطر crontab واحد | ملفا وحدة |
| التسجيل | بريد محلي، غالبًا غير مقروء | السجل، لكل وحدة |
| جولة فائتة (الجهاز مطفأ) | تُتخطى | تعمل مرة بـ Persistent=true |
| الاعتمادات/الترتيب | لا شيء — اعملها بنفسك في السكربت | اعتمادات وحدات كاملة |
| تأخير عشوائي | بنفسك مع $RANDOM | RandomizedDelaySec= |
| اختبار/تجربة الجدول | لا | systemd-analyze calendar |
| موجود في كل مكان | نعم — حاويات، BSD، مدمجات | يحتاج systemd (PID 1) |
| أعمال مستخدم بلا root | crontab -e | وحدات systemd --user |
قواعد إبهام: نشر عمل على جهازك الخاص ذي systemd → مؤقت. تذكير شخصي سريع أو جهاز لم تبنه → cron. وأي شيء فيه اعتمادات أو إعادة محاولة أو حاجة لمعرفة هل جرى فعلًا → مؤقت، دائمًا. والنمط الشائع مؤقت يشغّل عمل صيانة — كنسخة احتياطية ليلية بـ rsync — حيث تضمن Persistent=true حدوث النسخة حتى لو كان الجهاز نائمًا في الدقيقة المجدولة، وهو ما لا يقدمه cron ببساطة.
— mrsaynothing
— mrsaynothing
ملاحظات ميدانية في الذكاء الاصطناعي وLinux والاستضافة الذاتية.
ناقش هذا المقال على dev.to dev.to ↗
احصل على الشرح التطبيقي التالي بالبريد
رسالة واحدة لكل مقال. أصلح المشكلة وامضِ.
ما هذا؟llama.cpp مقابل Ollama: أيهما تشغّل في 2026؟
أعجبتك هذه الكتابات؟ بناء مثل هذا هو عملي. وظّفني