FlowingDev

شرح تعابير cron: لغة السفر عبر الزمن للمُجدوِلات

تعلم كيف تخبر تعابير cron، لغة الجدولة الصغيرة ولكن الجبارة، الحواسيب متى يجب تشغيل المهام المؤتمتة، من النسخ الاحتياطي إلى النشرات الإخبارية.

جرّب الأداة: محلل تعبير Cron

في جملة واحدة

تعبير cron هو سلسلة مضغوطة من الأحرف تحدد جدولًا زمنيًا متكررًا، وببساطة تخبر الحاسوب متى يجب عليه تشغيل مهمة مؤتمتة.

المشكلة التي يحلها

في العصور الرقمية المظلمة (حقبة السبعينيات)، إذا أردت أن يقوم الحاسوب بشيء ما تلقائيًا—لنقل، تنظيف الملفات المؤقتة عند منتصف الليل—كان عليك أن تكون مبدعًا. ربما كنت ستكتب سكربتًا ثقيلًا يعمل في حلقة لا نهائية، يتحقق من الوقت، ثم "ينام" لبعض الوقت. كانت طريقة فوضوية، غير فعالة، وعرضة للانهيار.

وهنا ظهر cron، وهو daemon (عملية تعمل في الخلفية) وُلد في مختبرات بيل (Bell Labs) في بدايات نظام Unix. الاسم هو إشارة إلى Chronos، تجسيد الزمن في الأساطير اليونانية، وهذا أقصى ما يمكن أن تصل إليه المهوسية (geekiness). كانت وظيفة Cron بسيطة ولكنها ثورية: قراءة قائمة من الأوامر والأوقات التي يجب أن تعمل فيها، ثم تنفيذها. كان نظام "اضبطها وانساها" لأتمتة المهام.

لكي تخبر cron متى يجب تشغيل الأشياء، كان بحاجة إلى لغة. ليست لغة مطولة تشبه الإنجليزية، بل شيء يمكن للحاسوب تحليله فورًا. تلك اللغة هي تعبير cron. إنه يحل المشكلة الأساسية لكيفية وصف أي جدول زمني متكرر يمكن تخيله—"كل يوم اثنين الساعة 9 صباحًا"، "في اليوم الأول والخامس عشر من كل شهر"، "كل 10 دقائق"—بطريقة موحدة وقابلة للتنبؤ. لولاها، لكان كل مطور يعيد اختراع عجلة الجدولة، ولكان خادمك عبارة عن فوضى عارمة من أوامر sleep() المخصصة.

كيف يعمل من الداخل

يبدو تعبير cron كسلسلة من الهراء لغير المطلعين، شيء مثل */15 9-17 * * 1-5. لكنه ليس سحرًا؛ بل هو لغة مصغرة عالية التنظيم. بمجرد أن تتعلم قواعدها، يمكنك قراءة وكتابة الجداول الزمنية كمحترف.

الحقول الخمسة لنهاية العالم (وأصدقاؤها)

يتكون تعبير cron القياسي من خمسة حقول، مفصولة بمسافات. يمثل كل حقل وحدة زمنية. فكر في الأمر كمجموعة من خمسة أقراص تديرها لتحديد اللحظة الصحيحة.

الحقل القيم المسموح بها الأحرف الخاصة المسموح بها
الدقيقة 0-59 * , - /
الساعة 0-23 * , - /
يوم من الشهر 1-31 * , - / ? L W
الشهر 1-12 أو JAN-DEC * , - /
يوم من الأسبوع 0-7 أو SUN-SAT * , - / ? L #

تضيف بعض تطبيقات cron الحديثة حقلًا سادسًا للسنة (1970-2099) أو حتى حقلًا سابقًا للثواني (0-59)، لكن التنسيق الكلاسيكي المكون من خمسة حقول هو الأكثر شيوعًا.

ملاحظة حول يوم الأسبوع: غالبًا ما يتم قبول كل من 0 و 7 ليوم الأحد. من الجيد الالتزام بترميز واحد (مثل 0=الأحد، 6=السبت).

الأحرف الخاصة: اللغة السرية

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

  • * (الـ "كل"): هذا هو الحرف البديل (wildcard). علامة النجمة في حقل الساعة تعني "كل ساعة من اليوم". علامة النجمة في كل حقل (* * * * *) تعني "كل دقيقة من كل ساعة من كل يوم من كل شهر..." لقد فهمت الفكرة.

  • , (الـ "و"): تعمل الفاصلة كفاصل في القائمة. 1,15 في حقل يوم من الشهر تعني "في اليوم الأول والخامس عشر من الشهر."

  • - (الـ "عبر"): تحدد الشرطة نطاقًا. 9-17 في حقل الساعة تعني "كل ساعة من الساعة 9 صباحًا حتى الساعة 5 مساءً."

  • / (الـ "خطوة"): تُستخدم الشرطة المائلة لتحديد الزيادات. */10 في حقل الدقيقة تعني "كل 10 دقائق". يمكنك دمجها مع نطاق أيضًا: 0-30/5 تعني "كل 5 دقائق خلال أول 30 دقيقة من الساعة" (أي عند الدقائق: 00، 05، 10، 15، 20، 25، 30).

  • ? (الـ "لا أهتم"): هذا الحرف صعب ولكنه مهم. لا يمكنك دائمًا تحديد كل من يوم من الشهر ويوم من الأسبوع لأنهما يمكن أن يتعارضا. ماذا يحدث إذا قلت "شغّل في اليوم الثالث عشر من الشهر و في يوم الجمعة"، ولكن اليوم الثالث عشر صادف يوم أربعاء؟ تحل ? هذه المشكلة بقولها: "لقد حددت أحد هذين الحقلين، لذا تجاهل الآخر." يمكنك تعيين الجدول الزمني إلى * * 13 * ? (شغّل في اليوم 13، لا يهمني أي يوم من أيام الأسبوع هو) أو * * ? * 5 (شغّل كل يوم جمعة، لا يهمني أي يوم من الشهر هو).

  • L (الـ "أخير"): L في حقل يوم من الشهر تعني "اليوم الأخير من الشهر" (أي 31 يناير، 28/29 فبراير، إلخ). في حقل يوم من الأسبوع، تعني "آخر X من الشهر". على سبيل المثال، 5L تعني "آخر يوم جمعة من الشهر."

  • W (الـ "يوم عمل"): 15W في يوم من الشهر تعني "أقرب يوم عمل إلى اليوم الخامس عشر من الشهر." إذا كان اليوم الخامس عشر يوم سبت، فستعمل المهمة يوم الجمعة 14. إذا كان اليوم الخامس عشر يوم أحد، فستعمل يوم الاثنين 16.

  • # (الـ "-надца"): هذا للعثور على أشياء مثل "ثالث يوم جمعة من الشهر." التعبير لذلك سيكون * * ? * 5#3.

لنجمع كل شيء معًا

دعنا نفك شفرة بعض التعابير الشائعة:

# التشغيل كل ليلة عند منتصف الليل
0 0 * * *
  • 0 في حقل الدقيقة: عند الدقيقة صفر (على رأس الساعة).
  • 0 في حقل الساعة: عند الساعة صفر (منتصف الليل).
  • * * * في الحقول الأخرى: كل يوم من كل شهر من كل أسبوع.
# التشغيل الساعة 8:30 صباحًا كل يوم عمل (الاثنين-الجمعة)
30 8 * * 1-5
  • 30 في حقل الدقيقة: بعد 30 دقيقة من بداية الساعة.
  • 8 في حقل الساعة: عند الساعة 8 صباحًا.
  • * * ليوم الشهر والشهر: لا يهم.
  • 1-5 ليوم الأسبوع: من الاثنين إلى الجمعة.
# التشغيل كل 15 دقيقة خلال ساعات العمل (9 صباحًا - 5 مساءً) في أيام الأسبوع
*/15 9-17 * * 1-5
  • */15: كل 15 دقيقة.
  • 9-17: للساعات 9، 10، 11، 12، 13، 14، 15، 16، و 17.
  • 1-5: من الاثنين إلى الجمعة.

قصص من الواقع

قضية النسخ الاحتياطي عند منتصف الليل

كانت قاعدة بيانات شركة ناشئة تنمو بسرعة. أدرك مدير النظام الرئيسي أنهم بحاجة إلى نسخ احتياطي يومي، لكن تشغيل سكربت النسخ الاحتياطي خلال النهار كان يبطئ التطبيق بأكمله. اشتكى المستخدمون، وضاعت مبيعات محتملة. الحل؟ مهمة cron بسيطة. قام بجدولة سكربت النسخ الاحتياطي المستهلك للموارد ليعمل الساعة 2 صباحًا، عندما يكون ضغط الزوار على الموقع شبه منعدم. أصبح التعبير 0 2 * * * البطل الصامت للشركة، مما يضمن أمان بياناتهم دون إزعاج مستخدم واحد. الدرس: قم بجدولة المهام المستهلكة للموارد بكثافة في أوقات الذروة المنخفضة للحفاظ على الأداء.

النشرة الإخبارية المنسية

أراد موقع تجارة إلكترونية صغير إرسال بريد إلكتروني بعنوان "عروض الأسبوع" كل صباح ثلاثاء لزيادة المبيعات. لشهور، كان شخص من قسم التسويق يدعى "ديف" مكلفًا بالنقر يدويًا على "إرسال" في الساعة 10 صباحًا. لكن في أحد الأسابيع، مرض ديف. لم يتم إرسال النشرة الإخبارية، وكانت مبيعات ذلك الثلاثاء بائسة. تدخل المطور الرئيسي وقام بأتمتة العملية. كتب سكربتًا لإرسال النشرة الإخبارية وربطه بمهمة cron: 0 10 * * 2. ومنذ ذلك الحين، أصبحت النشرة الإخبارية تُرسل كالساعة، بغض النظر عمن كان في المكتب. الدرس: أتمتة المهام المتكررة والحساسة للوقت لتحسين الموثوقية والقضاء على الخطأ البشري.

الذاكرة المخبئية (Cache) القديمة

كان موقع إخباري يفخر بنشر الأخبار العاجلة، لكن صفحته الرئيسية كانت تبدو بطيئة في كثير من الأحيان. تم تخزين محتواهم مؤقتًا (caching) لتحسين الأداء، ولكن لم يتم مسح الـ cache إلا عندما يقوم مطور بذلك يدويًا. هذا يعني أن المقالات الجديدة كانت تستغرق أحيانًا ساعات لتظهر. قام أحد المطورين بإعداد مهمة cron لمسح وإعادة بناء cache الموقع تلقائيًا كل خمس دقائق. مع التعبير */5 * * * *، أصبح الموقع أسرع بشكل كبير وأكثر حداثة، حيث أصبح من المضمون ظهور المحتوى الجديد في غضون دقائق. الدرس: استخدم cron للمهام "الروتينية" الدورية مثل إبطال صلاحية الـ cache للحفاظ على حيوية وأداء الأنظمة.

الأخطاء والفخاخ الشائعة

  • مشاكل المنطقة الزمنية: مشكلة كلاسيكية وهي "المهمة تعمل في الوقت الخطأ". تعمل مهام cron دائمًا تقريبًا باستخدام وقت نظام الخادم، والذي قد يكون UTC أو منطقة زمنية أخرى غير التي تتواجد فيها. جدولة مهمة للساعة 9 صباحًا بتوقيتك قد يعني أنها ستعمل في الساعة 2 ظهرًا بتوقيت الخادم. كن دائمًا على دراية بالمنطقة الزمنية لخادمك.

  • صدام يوم الشهر مقابل يوم الأسبوع: خطأ شائع يقع فيه المبتدئون هو وضع قيمة في كل من حقلي يوم الشهر ويوم الأسبوع (مثل، * * 1 FRI). معظم برامج cron تفسر هذا بشرط OR: "شغّل في اليوم الأول من الشهر أو في أي يوم جمعة." هذا نادرًا ما يكون ما تريده. إذا كنت تريد "أول جمعة من الشهر"، فأنت بحاجة إلى استخدام * * ? * 5#1 أو سكربت أكثر تعقيدًا. استخدم الحرف ? لتجنب الغموض.

  • نسيان إعادة توجيه المخرجات: افتراضيًا، أي شيء يطبعه السكربت الخاص بك على المخرج القياسي (standard output) أو الخطأ القياسي (standard error) يتم إرساله بالبريد الإلكتروني إلى المستخدم الذي يملك ملف crontab. هذا يبدو مفيدًا، لكنه يمكن أن يملأ صندوق البريد بسرعة بإشعارات غير مجدية. أفضل ممارسة هي التعامل مع المخرجات بشكل صريح: أرسلها إلى ملف سجل (>> /var/log/myjob.log 2>&1) أو تجاهلها إذا كنت لا تهتم (> /dev/null 2>&1).

  • المهمة المتداخلة: تعيين مهمة على * * * * * يعني "ابدأ نسخة جديدة من هذه المهمة في بداية كل دقيقة." إذا كانت مهمتك تستغرق 90 ثانية للتشغيل، فسيكون لديك عمليات تنفيذ متداخلة، مما قد يؤدي إلى "سباق الظروف" (race conditions)، واستنفاد الموارد، وجميع أنواع الفوضى.

  • البيئة المصغرة: الصدفة التفاعلية (interactive shell) الخاصة بك مليئة بمتغيرات البيئة المفيدة مثل $PATH. تعمل مهمة cron في بيئة قاحلة ومجردة. قد يفشل السكربت الخاص بك الذي يعمل بشكل مثالي من سطر الأوامر في cron لأنه لا يمكنه العثور على برامج مثل node أو python. الحل هو استخدام المسارات المطلقة لجميع الأوامر (على سبيل المثال، /usr/bin/node بدلاً من node) أو تعيين متغير PATH في أعلى ملف crontab الخاص بك.

لماذا يجب أن تكون على رادارك

قد تعتقد أن cron مخصص فقط لمديري الأنظمة من المدرسة القديمة، لكن حمضه النووي موجود في كل مكان.

  • الواجهة الخلفية (Backend) و DevOps: هو المعيار الفعلي لجدولة المهام الخلفية، من صيانة قواعد البيانات وتدوير السجلات إلى نشر الكود.
  • تطوير الويب: هل تحتاج إلى إرسال تقارير بريد إلكتروني يومية، أو مسح الـ cache، أو إنشاء خريطة موقع (sitemap)؟ cron هو أداتك.
  • المنصات السحابية: خدمات مثل AWS Lambda Scheduled Events و Google Cloud Scheduler تستخدم تعابير cron لتحديد مشغلاتها. هذه الصيغة هي لغة عالمية للجدولة، حتى في أحدث البيئات "اللاسيرفرية" (serverless).

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

تعمق أكثر

  • Wikipedia: cron - تاريخ ونظرة عامة على أداة cron نفسها.
  • crontab(5) - Linux man page - المرجع الفني الرسمي لتنسيق الملف وقواعده.
  • Crontab Guru - محرر تفاعلي عبر الإنترنت لتعابير cron يترجمها إلى لغة إنجليزية بسيطة. لا يقدر بثمن للتحقق من عملك.
  • The Open Group Base Specifications: crontab - معيار POSIX الذي يحدد ما يجب أن يفعله crontab.
  • Quartz CronTrigger Tutorial - نظرة عميقة على مجدول شهير قائم على Java يستخدم تنسيق تعبير cron موسع، بما في ذلك الثواني والمزيد من الأحرف الخاصة.

انتهينا من النظرية. حان وقت التطبيق — 100% في متصفحك.

جرّب الأداة: محلل تعبير Cron