التخطي إلى المحتوى
Toova
جميع الأدوات

شرح صيغة تعبير Cron

Toova

تعبيرات cron من تلك الموضوعات التي يتعلمها المطورون مرة ثم ينسون تفاصيلها ويعودون للبحث عنها كل ستة أشهر. سلسلة مكوَّنة من خمسة أحرف كـ 30 9 * * 1-5 تُرمِّز جدولاً زمنياً بالغ الدقة — "كل يوم عمل في 9:30 صباحاً" — لكن الصيغة تنطوي على حالات حافة كافية لتسبب إرباكاً حقيقياً: الحقول ذات الفهرسة الصفرية مقابل الفهرسة الابتدائية، كون الأحد يساوي 0 و7 في آنٍ واحد، الفرق بين معيار Unix وامتداد Quartz ذي الستة حقول، وسلوك قيم الخطوة المدمجة مع النطاقات.

يغطي هذا الدليل صيغة cron من مبادئها الأولى، ثم يتناول كل حرف خاص بأمثلة ملموسة. سواء كنت تكتب مهمة cron لخدمة Linux، أو تُعدُّ جدول GitHub Actions، أو تُنشئ قاعدة AWS EventBridge، فالمفاهيم الأساسية ذاتها تنطبق — مع شرح لبعض الفروق المهمة بين المنصات.

الحقول الخمسة القياسية

يحتوي تعبير cron القياسي على خمسة حقول مفصولة بمسافات، تُقرأ من اليسار إلى اليمين: الدقيقة والساعة ويوم الشهر والشهر ويوم الأسبوع. يُقيِّد كل حقل وقت تشغيل المهمة على ذلك البُعد. تعمل المهمة فقط عندما تتطابق الحقول الخمسة في الوقت ذاته.

# Field       Position  Range         Special chars
# ─────────────────────────────────────────────────
# Minute          1      0-59          * / , -
# Hour            2      0-23          * / , -
# Day of month    3      1-31          * / , - ? L W
# Month           4      1-12 or JAN-DEC   * / , -
# Day of week     5      0-7 (0=7=Sun) or SUN-SAT  * / , - ? L #

قراءة تعبير كـ 30 9 * * 1-5: الدقيقة 30، الساعة 9، أي يوم من الشهر، أي شهر، يوم الأسبوع من 1 إلى 5 (الاثنين إلى الجمعة). النتيجة: 9:30 صباحاً كل يوم عمل.

الحقل 1: الدقيقة (0-59)

يُحدِّد حقل الدقيقة الدقيقة أو الدقائق التي تعمل فيها المهمة. 0 تعني بداية الساعة، 30 تعني منتصفها، 59 تعني دقيقة قبل انتهاء الساعة. استخدام * يُشغِّل المهمة كل دقيقة.

الحقل 2: الساعة (0-23)

تستخدم الساعات نظام 24 ساعة. 0 منتصف الليل، 12 الظهر، 23 الحادية عشرة مساءً. لا يوجد في cron تمييز صباح/مساء — مهمة في 9:00 صباحاً هي الساعة 9، ومهمة في 9:00 مساءً هي الساعة 21.

الحقل 3: يوم الشهر (1-31)

على خلاف الحقول الأخرى، يبدأ يوم الشهر من 1 لا من 0. القيم الصالحة من 1 إلى 31. إذا حدَّدت يوماً غير موجود في شهر بعينه (مثلاً اليوم 31 في أبريل)، لا تعمل المهمة في ذلك الشهر ببساطة. في Quartz، يمثِّل الحرف الخاص L آخر يوم في الشهر بصرف النظر عن عدد أيامه.

الحقل 4: الشهر (1-12)

تتراوح قيم الشهر من 1 (يناير) إلى 12 (ديسمبر). تقبل كثير من الجداول الزمنية أيضاً اختصارات مكوَّنة من ثلاثة أحرف: JAN وFEB وMAR وAPR وMAY وJUN وJUL وAUG وSEP وOCT وNOV وDEC. وهي غير حساسة لحالة الأحرف في معظم التطبيقات.

الحقل 5: يوم الأسبوع (0-7)

هذا الحقل يحمل أكثر الإرث التاريخي. كلٌّ من 0 و7 يمثلان الأحد — وهذه ميزة توافقية من Unix القديم. الاثنين 1، الثلاثاء 2، حتى السبت 6. الأسماء المكوَّنة من ثلاثة أحرف تعمل هنا أيضاً: SUN وMON وTUE وWED وTHU وFRI وSAT.

عند تحديد يوم الشهر ويوم الأسبوع معاً (لا يساوي أيٌّ منهما *)، تستخدم معظم خدمات Unix cron منطق OR: تعمل المهمة إذا تطابق أي من الحقلين. هذا يفاجئ كثيراً من المطورين. إن أردت "اليوم الخامس عشر لكن فقط إذا كان يوم عمل"، يجب معالجة ذلك في السكريبت نفسه، لا في تعبير cron.

الحروف الخاصة

النجمة (*) — كل قيمة

تطابق النجمة كل قيمة صالحة في الحقل. في حقل الدقيقة، * تعني الدقائق من 0 إلى 59. في حقل الشهر، تعني جميع الاثني عشر شهراً. وهي الحرف الأكثر شيوعاً في تعبيرات cron.

الشرطة المائلة (/) — قيم الخطوة

تُعرِّف الشرطة المائلة فترة خطوة. */5 في حقل الدقيقة تعني "كل 5 دقائق". بدقة أكبر، تعني "كل قيمة في النطاق قابلة للقسمة على 5 بدءاً من أول قيمة في النطاق". فـ */5 في الدقائق تُقيِّم إلى 0 و5 و10 و15 و20 و25 و30 و35 و40 و45 و50 و55.

يمكن دمج الخطوات مع النطاقات: 10-30/5 في حقل الدقيقة تعني كل 5 دقائق بين الدقيقة 10 والدقيقة 30، مُنتِجةً 10 و15 و20 و25 و30. تبدأ الخطوة من الحد الأدنى للنطاق.

الفاصلة (,) — قائمة من القيم

تُنشئ الفواصل قائمة من قيم محددة. 1,3,5 في حقل الشهر تعني يناير ومارس ومايو. 9,17 في حقل الساعة تعني 9:00 و17:00. يمكن سرد أي عدد من القيم ودمجها مع بنى أخرى.

الشرطة (-) — النطاق

تُحدِّد الشرطة نطاقاً شاملاً. 1-5 في حقل يوم الأسبوع تعني الاثنين إلى الجمعة. 9-17 في حقل الساعة تعني الساعة 9 صباحاً حتى الساعة 5 مساءً. النطاقات شاملة للطرفين.

علامة الاستفهام (?) — بدون قيمة محددة (Quartz فقط)

لا تدعم Unix cron القياسية ?. في Quartz Scheduler، تُستخدم في حقلي يوم الشهر أو يوم الأسبوع بمعنى "لا أبالي بهذا الحقل". لأن Quartz لا يستطيع دائماً حل التعارضات بين يوم الشهر ويوم الأسبوع، يجب ضبط أحدهما على ? عند تحديد الآخر. 0 0 15 * ? تعني "اليوم الخامس عشر من كل شهر، أي يوم من الأسبوع." 0 0 ? * MON تعني "كل اثنين، أي يوم من الشهر."

L — الأخير (Quartz فقط)

L في حقل يوم الشهر تعني آخر يوم في الشهر. L في حقل يوم الأسبوع تعني السبت، أو عند دمجها مع رقم (مثلاً 5L)، آخر مرة لذلك اليوم في الشهر. 5L هي آخر جمعة في الشهر.

W — أقرب يوم عمل (Quartz فقط)

W في حقل يوم الشهر تجد أقرب يوم عمل (الاثنين-الجمعة) لليوم المحدد. 15W تعني أقرب يوم عمل للخامس عشر. إذا كان الخامس عشر سبتاً، تعمل المهمة في الرابع عشر (الجمعة). وإن كان أحداً، تعمل في السادس عشر (الاثنين). W لا تتجاوز حدود الشهر.

الهاشتاج (#) — يوم الأسبوع رقم N في الشهر (Quartz فقط)

# تُحدِّد تكرار N ليوم الأسبوع في الشهر. 5#2 تعني الجمعة الثانية في الشهر. 2#1 تعني أول ثلاثاء. إذا لم يتحقق التكرار المحدد في شهر بعينه، لا تعمل المهمة في ذلك الشهر.

أنماط Cron الشائعة

# Every minute
* * * * *

# Every day at midnight (00:00)
0 0 * * *

# Every day at 9:30 AM
30 9 * * *

# Every Monday at 8:00 AM
0 8 * * 1

# First day of every month at noon
0 12 1 * *

# Every 15 minutes
*/15 * * * *

# Weekdays at 6:00 PM
0 18 * * 1-5

يمكن اختبار وتحقق أي من هذه التعبيرات باستخدام أداة محلل Cron، التي تعرض أوقات التشغيل الخمسة التالية لأي تعبير وتُبرز الصيغ غير الصالحة. استخدم محوِّل الطابع الزمني إذا كنت بحاجة إلى التحقق مما يقابل طابعاً زمنياً معيناً في منطقتك الزمنية المحلية.

امتداد 6 حقول: Quartz Scheduler

يُضيف Quartz Scheduler — المستخدم بشكل واسع في نظام Java البيئي وتبنَّته كثير من جداول المؤسسات — حقل ثوانٍ إلزامياً في بداية التعبير. تصبح الصيغة: ثانية دقيقة ساعة يوم-الشهر شهر يوم-الأسبوع.

# Quartz 6-field: second minute hour day month weekday
# Run at exactly 00 seconds, 30 minutes, every hour
0 30 * * * ?

# Run at midnight every day
0 0 0 * * ?

# Run every 5 seconds
0/5 * * * * ?

# Last day of month at 10:00 AM
0 0 10 L * ?

# Last Friday of month at 3:00 PM
0 0 15 ? * 6L

الفروق الرئيسية عن cron القياسي: حقل الثواني (0-59) أول وإلزامي؛ يوم الأسبوع يستخدم 1 (الأحد) إلى 7 (السبت) لا 0-6؛ ? مطلوب في يوم الشهر أو يوم الأسبوع عند تحديد الآخر؛ والحروف L وW و# حروف خاصة صالحة.

لا تلصق تعبير Quartz في crontab Unix دون حذف حقل الثواني وضبط ترقيم يوم الأسبوع. المحللات غير قابلة للتبادل.

Cron في أنظمة مختلفة

Linux/Unix crontab (Vixie cron)

الصيغة الأصلية والأكثر شيوعاً. خمسة حقول مفصولة بمسافات يتبعها الأمر. متغيرات البيئة كـ CRON_TZ أو TZ تُعيِّن المنطقة الزمنية. تُعدَّل crontabs المستخدمين بـ crontab -e؛ تقيم crontabs النظام في /etc/cron.d/. الاختصارات @reboot و@daily و@hourly و@weekly و@monthly مدعومة على نطاق واسع كأسماء مستعارة للأنماط الشائعة.

GitHub Actions

يستخدم GitHub Actions صيغة cron القياسية ذات 5 حقول، لكن المنطقة الزمنية هي دائماً UTC — لا توجد طريقة لتحديد منطقة زمنية محلية في التعبير نفسه. تُقيَّم التعبيرات على مستوى المستودع لا لكل مهمة. لاحظ أن سير العمل المجدوَل قد يتأخر عدة دقائق خلال فترات الحمل الزائد على بنية GitHub التحتية.

# GitHub Actions schedule syntax (5-field UTC only)
on:
  schedule:
    # Run every day at 02:30 UTC
    - cron: '30 2 * * *'
    # Run every Monday at 09:00 UTC
    - cron: '0 9 * * 1'

تُشير وثائق GitHub Actions cron الرسمية إلى أن الحد الأدنى للفترة الزمنية هو 5 دقائق — التعبيرات التي تعمل بتكرار أعلى من ذلك يتم تجاهلها بصمت.

AWS EventBridge (CloudWatch Events)

يدعم AWS EventBridge تعبيرات المعدل (rate(5 minutes)) وتعبيرات cron. متغيِّرهم من cron يحتوي 6 حقول لكنه يختلف عن Quartz: يوم الأسبوع يستخدم أسماء Sun-Sat أو 1-7 حيث 1 هو الأحد، جميع الأوقات بتوقيت UTC، ويجب أن يكون أحد يوم الشهر أو يوم الأسبوع ?. لا تدعم AWS الحرفين W أو #.

# AWS EventBridge (cron in UTC, 6-field variant)
# Runs every day at 10:00 AM UTC
cron(0 10 * * ? *)

# Runs at 6:00 PM on the last weekday of every month
cron(0 18 L-1 * ? *)

Kubernetes CronJob

يستخدم Kubernetes CronJob صيغة cron القياسية ذات 5 حقول. المنطقة الزمنية الافتراضية هي منطقة عملية kube-controller-manager (عادةً UTC على المجموعات المُدارة). أضاف Kubernetes 1.25 الحقل timeZone إلى مواصفة CronJob، مما يسمح بإعداد المنطقة الزمنية لكل مهمة دون الاعتماد على منطقة النظام الزمنية.

Node.js (node-cron / cron npm)

تدعم حزمة node-cron الشهيرة التعبيرات القياسية ذات 5 حقول بالإضافة إلى حقل 6 اختياري للثواني مُضاف في البداية. حزمة cron متوافقة مع Quartz. كلتاهما تدعمان سلاسل المناطق الزمنية (مثلاً America/New_York) كخيار في الدالة البانية. راجع وثائق حزمتك المحددة للتأكد من الصيغة المتوقعة.

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

افتراضات المنطقة الزمنية

يعمل cron في المنطقة الزمنية للخادم أو الحاوية، وهي كثيراً ما تكون UTC في البيئات السحابية. مهمة مُعدَّة للعمل في "9 صباحاً بتوقيت العمل" وتُكتب كـ 0 9 * * * ستعمل في 9 صباحاً UTC — وهو ما قد يكون 4 صباحاً أو 5 صباحاً أو 11 صباحاً في منطقتك الزمنية حسب الإزاحة والتوقيت الصيفي. اضبط دائماً CRON_TZ، أو استخدم حقل المنطقة الزمنية في جدولك الزمني، أو حوِّل وقتك المستهدف إلى UTC صراحةً. تُساعد أداة محوِّل المناطق الزمنية في إيجاد المكافئ بتوقيت UTC لأي وقت محلي في أي منطقة زمنية.

منطق OR في يوم الشهر / يوم الأسبوع

في Unix cron، عندما يكون كلا حقلي يوم الشهر ويوم الأسبوع غير *، تعمل الخدمة إذا تطابق أي من الحقلين. فـ 0 9 15 * 1 تعمل في اليوم الخامس عشر من كل شهر وكل اثنين — لا فقط في اثنين يصادف الخامس عشر. لتحقيق منطق AND، يجب تطبيق الفحص الإضافي داخل السكريبت.

الخلط بين قيم الخطوة والنطاقات

*/5 تعني "كل 5 دقائق بدءاً من 0" (0، 5، 10...). 5/5 تعني "كل 5 دقائق بدءاً من 5" (5، 10، 15...). 5-30/5 تعني "كل 5 دقائق بين الدقيقة 5 والدقيقة 30" (5، 10، 15، 20، 25، 30). دمج هذه مع النطاقات قد يُنتج نتائج غير متوقعة إن لم تكن دقيقاً في قيمة البداية.

فخ "كل ثانية"

دقة cron الدنيا في صيغة الخمسة حقول القياسية هي دقيقة واحدة. لا يمكن جدولة مهمة cron لتعمل كل ثانية أو كل بضع ثوانٍ باستخدام crontab. للجدولة دون الدقيقة، استخدم مؤقتاً على مستوى اللغة (setInterval في Node.js، أو APScheduler في Python) أو نظام طوابير مُصمَّم لهذا الغرض بدلاً من cron. إذا احتجت كل 30 ثانية، شغِّل مهمتين: واحدة في * * * * * وأخرى تنتظر 30 ثانية قبل التنفيذ.

إغفال ترقيم الشهر

في cron القياسي، تتراوح الشهور من 1 (يناير) إلى 12 (ديسمبر). في بعض واجهات التاريخ في لغات البرمجة، تبدأ الشهور من الصفر (0 = يناير، 11 = ديسمبر). إذا كنت تُولِّد تعبيرات cron برمجياً من كائنات التاريخ، تحقق من أنك لست منزاحاً بمقدار واحد في حقل الشهر.

تحقَّق من تعبيراتك

تعرض أداة محلل Cron على Toova أوقات التشغيل المجدوَلة الخمسة التالية لأي تعبير، وتدعم صيغتي Quartz ذات الخمسة والستة حقول، وتُبرز القيم غير الصالحة مباشرةً. للتحقق السريع، crontab.guru أداة تفاعلية معروفة تصف التعبيرات بلغة عادية. كلتاهما مفيدة للإشارة المرجعية.

عند العمل مع الطوابع الزمنية وأوقات الجداول، تُترجم أداة محوِّل الطابع الزمني بين الطوابع الزمنية Unix والتواريخ المقروءة عبر أي منطقة زمنية. للمهام التي تنطوي على جدولة حساسة للمنطقة الزمنية، اقرنها بأداة محوِّل المناطق الزمنية للتحقق من الإزاحات وانتقالات التوقيت الصيفي والمكافئات بتوقيت UTC قبل كتابة تعبيرك النهائي.