سؤال لماذا لا يعمل crontab الخاص بي ، وكيف يمكنني استكشاف ذلك؟


هذا ال السؤال الكنسي حول استخدام cron & crontab.

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

الجواب "لماذا لا يعمل crontab الخاص بي ، وكيف يمكنني استكشاف ذلك؟"يمكن رؤيته أدناه. هذا يعالج cron نظام مع crontab سلط الضوء عليها.


193
2017-11-17 04:51


الأصل


هذا هو خداع كبير من أسباب لماذا لا يعمل crontab على AskUbuntu. - Dan Dascalescu


الأجوبة:


كيفية إصلاح جميع المشاكل / المشاكل المتعلقة بـ crontab (Linux)


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


أولاً ، المصطلحات الأساسية:

  • كرون (8) هو البرنامج الذي ينفذ الأوامر المجدولة.
  • كرونتاب (1) هو البرنامج المستخدم لتعديل ملفات crontab المستخدم (5).
  • كرونتاب (5) هو ملف لكل مستخدم يحتوي على تعليمات لـ cron (8).

بعد ذلك ، التعليم عن cron:

قد يكون لدى كل مستخدم على نظام ملف crontab الخاص به. موقع ملفات crontab الجذر والمستخدم يعتمد على النظام ولكن بشكل عام أدناه /var/spool/cron.

هناك على نطاق المنظومة /etc/crontab الملف ، و /etc/cron.d قد يحتوي الدليل على شظايا crontab والتي تقرأ أيضا وتتصرف من قبل cron. بعض توزيعات لينكس (مثل ريد هات) أيضا /etc/cron.{hourly,daily,weekly,monthly} وهي عبارة عن أدلة ، سيتم تنفيذ نصوصها الداخلية كل ساعة / يوم / أسبوع / شهر ، مع امتياز الجذر.

الجذر يمكن دائما استخدام القيادة crontab؛ المستخدمين العاديين قد يكون أو لا يتم منحهم حق الوصول. عندما تقوم بتحرير ملف crontab باستخدام الأمر crontab -e وحفظه ، crond يتحقق من صحتها الأساسية ولكن لا يضمن تشكيل ملف crontab الخاص بك بشكل صحيح. هناك ملف يسمى cron.deny والتي ستحدد المستخدمين الذين لا يمكنهم استخدام كرون. ال cron.deny موقع الملف يعتمد على النظام ويمكن حذفه مما يسمح لجميع المستخدمين باستخدام كرون.

إذا لم يتم تشغيل الكمبيوتر أو لم يتم تشغيل خداع crond ، وتم تمرير التاريخ / الوقت لأمر لتشغيل ، فلن يصطدم crond ويشغل الاستعلامات السابقة.

تفاصيل crontab ، كيفية صياغة أمر:

يتم تمثيل الأمر crontab بخط واحد. لا يمكنك استخدام \ لتوسيع أمر عبر خطوط متعددة. التجزئة (#) تمثل علامة تعليق مما يعني أن أي شيء على هذا الخط يتم تجاهله بواسطة cron. يتم تجاهل المسافات البيضاء والخطوط الفارغة.

كن حذرًا عند استخدام النسبة المئوية (%) تسجيل الدخول في الأمر الخاص بك. ما لم يتم هربهم \% يتم تحويلها إلى خطوط جديدة وكل شيء بعد أول غير هرب % يتم تمريرها إلى الأمر الخاص بك على stdin.

يوجد تنسيقان لملفات crontab:

  • crontabs المستخدم

    # Example of job definition:
    # .---------------- minute (0 - 59)
    # |  .------------- hour (0 - 23)
    # |  |  .---------- day of month (1 - 31)
    # |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
    # |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7)
    # |  |  |  |  |
    # *  *  *  *  *   command to be executed
    
  • النظام على نطاق واسع /etc/crontab و /etc/cron.d فتات

    # Example of job definition:
    # .---------------- minute (0 - 59)
    # |  .------------- hour (0 - 23)
    # |  |  .---------- day of month (1 - 31)
    # |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
    # |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7)
    # |  |  |  |  |
    # *  *  *  *  * user-name  command to be executed
    

لاحظ أن هذا الأخير يتطلب اسم مستخدم. سيتم تشغيل الأمر كمستخدم مسمى.

تمثل الحقول الخمسة الأولى من الخط الوقت (الأوقات) عند تشغيل الأمر. يمكنك استخدام الأرقام أو أينما ينطبق يوم / شهر أسماء في مواصفات الوقت.

  • يتم فصل الحقول بمسافات أو علامات تبويب.
  • غيبوبة (,) يستخدم لتحديد قائمة مثل 1،4،6،8 مما يعني تشغيل في 1،6،6،8.
  • يتم تحديد النطاقات باستخدام شرطة (-) ويمكن دمجها مع القوائم ، على سبيل المثال. 1-3،9-12 أي ما بين 1 و 3 ثم بين 9 و 12.
  • ال / يمكن استخدام الحرف لتقديم خطوة على سبيل المثال. 2/5 مما يعني البدء من 2 ثم كل 5 (2،7 ، 12 ، 17 ، 22 ...). انهم لا يلفون الماضي.
  • النجمة (*) في حقل يشير إلى النطاق الكامل لهذا الحقل (على سبيل المثال ، 0-59 للحقل الدقيق).
  • يمكن دمج النطاقات والخطوات على سبيل المثال ، */2 يشير إلى الحد الأدنى للحقل ذي الصلة ، ثم كل 2 على سبيل المثال ، 0 للدقائق (0،2 ... 58) ، 1 للأشهر (1،3 ... 11) إلخ.

تصحيح أوامر cron

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

MAILTO=user@somehost.tld
1 2 * * * /path/to/your/command

التقاط الإخراج بنفسك

1 2 * * *  /path/to/your/command &>/tmp/mycommand.log

الذي يلتقط stdout و stderr إلى /tmp/mycommand.log

انظر إلى السجلات تسجل cron إجراءاتها عبر syslog ، والتي (حسب إعدادك) غالباً ما تذهب إلى /var/log/cron أو /var/log/syslog.

إذا لزم الأمر ، يمكنك تصفية بيانات cron على سبيل المثال.

grep CRON /var/log/syslog 

والآن بعد أن انتهينا من أساسيات cron ، حيث توجد الملفات وكيفية استخدامها ، دعنا نلقي نظرة على بعض المشاكل الشائعة.

تحقق من تشغيل cron

إذا لم يتم تشغيل cron فلن يتم جدولة الأوامر الخاصة بك ...

ps -ef | grep cron | grep -v grep

يجب أن تحصل على شيء من هذا القبيل

root    1224   1  0 Nov16 ?    00:00:03 cron

أو

root    2018   1  0 Nov14 ?    00:00:06 crond

إذا لم تقم بإعادة تشغيله

/sbin/service cron start

أو

/sbin/service crond start

قد تكون هناك طرق أخرى. استخدم ما يوفره توزيعة الخاص بك.

كرون يدير أمرك في بيئة مقيدة.

من المحتمل أن تكون متغيرات البيئة المتوفرة محدودة للغاية. عادة ، ستحصل فقط على بعض المتغيرات المحددة ، مثل $LOGNAME، $HOMEو $PATH.

من الملاحظ خاصة هو PATH يقتصر على /bin:/usr/bin. الغالبية العظمى من "لا تعمل برنامجي النصي cron" تنتج عن هذا المسار التقييدي. إذا كان الأمر في موقع مختلف ، فيمكنك حل ذلك بطريقتين:

  1. توفير المسار الكامل لأمرك.

    1 2 * * * /path/to/your/command
    
  2. توفير PATH مناسبة في ملف crontab

    PATH=/usr:/usr/bin:/path/to/something/else
    1 2 * * * command 
    

إذا كان الأمر يتطلب متغيرات بيئة أخرى ، فيمكنك تعريفها في ملف crontab أيضًا.

يعمل cron مع الأمر cwd == $ HOME

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

لا يعمل الأمر الأخير في crontab الخاص بي

يتطلب Cron بشكل عام أن يتم إنهاء الأوامر بخط جديد. تحرير crontab الخاص بك؛ اذهب إلى نهاية السطر الذي يحتوي على الأمر الأخير وقم بإدخال سطر جديد (اضغط على enter).

تحقق من تنسيق crontab

لا يمكنك استخدام crontab بتنسيق crontab المستخدم لـ / etc / crontab أو الأجزاء في /etc/cron.d والعكس. لا يتضمن مستخدم crontab المنسق اسم مستخدم في الموضع السادس لصف ، بينما يتضمن crontab المنسق الخاص بالنظام اسم المستخدم ويقوم بتشغيل الأمر كهذا المستخدم.

أضع ملفًا في /etc/cron.{hourly، daily، weekly،monthly} ولا يتم تشغيله

  • تحقق من أن اسم الملف لا يحتوي على أي إضافة تشغيل أجزاء
  • تأكد من أن الملف قام بتنفيذ الأذونات.
  • أخبر النظام ما يجب استخدامه عند تنفيذ البرنامج النصي الخاص بك (على سبيل المثال #!/bin/sh في القمة)

تاريخ الخنازير ذات الصلة

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

علامات النسبة المئوية ، مرة أخرى

للتأكيد على النصيحة بشأن علامات النسبة المئوية ، إليك مثال لما يفعله cron معهم:

# cron entry
* * * * * cat >$HOME/cron.out%foo%bar%baz

سيقوم بإنشاء ملف ~ / cron.out الذي يحتوي على الأسطر الثلاثة

foo
bar
baz

هذا هو تدخلي خاصة عند استخدام date أمر. تأكد من الفرار من علامات النسبة المئوية

* * * * * /path/to/command --day "$(date "+\%Y\%m\%d")"

274
2017-10-09 15:29



قد ترغب أيضًا في الإشارة إلى قسم "env المقيدة" الذي قد يحتاج LD_LIBRARY_PATH أيضًا إلى تعيين أي أدلة إضافية في حالة فشل مهمة cron الخاصة بك بسبب عدم إمكانية العثور على مكتبات مشتركة. - DavidJ
لاحظ أنه حتى يمكنك كتابة شيء من هذا القبيل: 35 1،5-23 / 2 * * * do_something بدلاً من 35،1،5،7،9 ، .. * * * بالإضافة إلى ذلك crontab.guru يترجم الإدخالات التي تقوم بها إلى لغة البشر. - Dennis Nolte
لا يعمل التقاط الإخراج بالنسبة لي ، قد يكون بسبب قذيفة sh. أعتقد أن هذا أكثر قابلية للحمل: ... /path/to/your/command >/tmp/mycommand.log 2>&1 - chus
هذا العمل بالنسبة لي: sudo apt-get install postfix - jmunsch
وظيفة cron يعتمد أيضا على مدى ثقل الملف؟ لأنني ركضت العالم مرحبا بسيطة في الثعبان مع كرون ، لأنها عملت. لكن شفرتي الثانية كانت ثقيلة بعض الشيء ، وعادة ما يتم تشغيلها ولكن مع cron لا يعطي أي إخراج في الملف. - Devendra Bhat


إذا توقفت cronjobs عن العمل ، فتحقق من أن كلمة المرور الخاصة بك لم تنتهِ صلاحيتها ، لأنه بمجرد وجودها ، تتوقف جميع وظائف cron.
سيكون هناك رسائل في /var/log/messages مشابهة لتلك الواردة أدناه والتي توضح مشكلات مصادقة المستخدم:

(username) FAILED to authorize user with PAM (Authentication token is no longer valid; new one required)


18
2018-02-04 20:29



فقط حصلت على هذا أيضا (ملف رسالة خطأ / فار / سجل / سجل النظام بالنسبة لي). في حالتي ، صندوق DigitalOcean يقوم ، عند إنشاء الوقت ، بإعادة تعيين كلمة مرور الجذر (اختياريًا) إلى كلمة أخرى ، وعلى ما يبدو إلى أن تذهب إلى هناك وتغييرها ، ولا تعمل جميع مهام cron. المشكله. الإصلاح هو شيء من هذا القبيل sudo -u root passwd - rogerdpack


يحتوي Debian Linux ومشتقاته (أوبونتو ، والنعناع ، إلخ) على بعض الخصائص التي قد تمنع تنفيذ مهامك في cron ؛ على وجه الخصوص ، الملفات في /etc/cron.d، /etc/cron.{hourly,daily,weekly,monthly} يجب:

  • تكون مملوكة للجذر
  • يكون فقط قابل للكتابة بواسطة الجذر
  • لا يمكن كتابتها من قبل مجموعة أو مستخدمين آخرين
  • لديك اسم دون أي نقطة ". أو أي شخصية خاصة أخرى ولكن "-" و "_".

آخر واحد يؤذي المستخدمين المطمئنين بشكل منتظم. على وجه الخصوص أي برنامج نصي في أحد هذه المجلدات اسمه whatever.sh، mycron.py، testfile.pl، وما إلى ذلك ليس يتم تنفيذه ، من أي وقت مضى.

من وجهة نظري ، كانت هذه النقطة بالذات السبب الأكثر شيوعًا لوجود cronjob غير قابل للتنفيذ في دبيان ومشتقاته.

نرى man cron لمزيد من التفاصيل ، إذا لزم الأمر.


15
2017-11-17 14:37





جداول غير شائعة وغير منتظمة

Cron هي كل الأشياء التي تعتبر جدولة أساسية ، وبناء الجملة لا يسمح بسهولة للمسؤول بصياغة جداول غير شائعة أكثر بعض الشيء.

النظر في الوظيفة التالية التي سيتم شرحها بشكل عام "يركض command كل 5 دقائق ":

*/5 * * * * /path/to/your/command

مقابل:

*/7 * * * * /path/to/your/command

التي لا دائما يركض command كل 7 دقائق.

تذكر أن / يمكن استخدام الحرف لإدخال خطوة ولكن لا يتم التفاف الخطوات بعد نهاية سلسلة مثل. */7 الذي يطابق كل دقيقة 7 من الدقائق 0-59  بمعنى 0،7،14،21،28،35،42،49،56 ولكن بين ساعة و التالية سيكون هنالك فقط 4 دقائق بين الدفعات، بعد 00:56 تبدأ سلسلة جديدة في 01:00، 01:07 إلخ (ولن يتم تشغيل الدُفعات 01:03 ، 01:10 ، 01:17 إلخ.).


ماذا تفعل بدلا من ذلك؟

إنشاء دفعات متعددة

بدلاً من مهمة cron واحدة ، إنشاء دفعات متعددة التي ضمت النتيجة في الجدول المطلوب.

على سبيل المثال لتشغيل دفعة كل 40 دقيقة (00:00 ، 00:40 ، 01:20 ، 02:00 وما إلى ذلك) إنشاء دفعتين ، واحدة تعمل مرتين على الساعات الزوجية والثانية التي تدير فقط الساعات الفردية:

# The following lines create a batch that runs every 40 minutes i.e.

# runs on   0:00, 0:40,        02:00, 02:40         04:00 etc to 22:40
0,40 */2 * * * /path/to/your/command

# runs on               01:20,               03:20,       etc to 23:20
20 1/2 * * * /path/to/your/command

# Combined: 0:00, 0:40, 01:20, 02:00, 02:40, 03:20, 04:00 etc.

قم بتشغيل دفعاتك بشكل أقل 

بدلاً من تشغيل الدفعة كل 7 دقائق ، وهو جدول زمني يصعب تفكيكه على دفعات متعددة ، قم بتشغيله كل 10 دقائق بدلاً منه.

قم بتشغيل دفعاتك بشكل متكرر 

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

بدلا من ذلك ، التفكير بشكل مختلف وإنشاء cronjob التي سوف تفشل بأمان عند التشغيل السابق لم ينته بعد ، ولكن التي سوف تعمل على خلاف ذلك. انظر الى هذا Q & A:

* * * * * /usr/bin/flock -n /tmp/fcj.lockfile /usr/local/bin/frequent_cron_job --minutely

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

في باش seven-minute-job ستبدو شيئًا مثل:

#!/bin/bash
# seven-minute-job
# This batch will only run when 420 seconds (7 min) have passed
# since the file /tmp/lastrun was either created or updated

if [ ! -f /tmp/lastrun ] ; then
    touch /tmp/lastrun
fi

if [ $(( $(date +%s) - $(date -r /tmp/lastrun +%s) )) -lt 420 ] ; then
    echo "The minimum interval of 7 minutes between successive batches hasn't passed yet."
    exit
fi

echo "Start running your batch"

date > /tmp/lastrun

والتي يمكنك بعدها (محاولة) بأمان تشغيل كل دقيقة:

* * * * * /path/to/your/seven-minute-job

لا تستخدم كرون

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


10
2017-10-23 04:45





PHP محددة

إذا كان لديك وظيفة كرون مثل:

php /bla/bla/something.php >> /var/logs/somelog-for-stdout.log

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

PHP بشكل افتراضي لا ترسل أخطاء إلى STDOUT. @نرى https://bugs.php.net/bug.php؟id=22839

لإصلاح هذا ، قم بإضافة php.ini cli`s أو في السطر الخاص بك (أو في غلاف bash الخاص بـ PHP):

  • --define display_startup_errors = 1
  • --define display_errors = 'stderr'

سيسمح لك الإعداد الأول أن يكون لديك فاضل مثل "Memory oops" و 2 - لإعادة توجيههم جميعًا إلى STDERR. فقط بعد أن تنام بشكل جيد ، سيتم إرسال جميع الرسائل إلى بريد الجذر بدلاً من تسجيلها فقط.


8



تم إغلاق تقرير الخطأ هذا في عام 2007 مع وضع التصحيح الذي تتم إضافته إلى فروع PHP 5.2+. هل أنت متأكد من أن هذا مطلوب؟ لقد حاولت للتو على PHP 5.4 ويبدو أنه يعمل بشكل جيد. (لا تزال هناك حاجة ل PHP 4 على الرغم من). - Xeoncross
Xeoncross انظر تاريخ الإجابة :) - gaRex
نعم ، هذا هو ما أحيرني منذ أن أجبت في عام 2013 وعاد التذكرة في عام 2007. - Xeoncross