سؤال لماذا لا تعمل مخطوطات crontab؟


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

  1. ترميز كرنتاب خاطئ
  2. مشكلة الأذونات
  3. متغيرات البيئة

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

الرجاء تضمين سبب واحد لكل إجابة - تفاصيل حول سبب عدم تنفيذه - وإصلاح (الإصلاحات) لهذا السبب.

يرجى كتابة المشاكل الخاصة بالكرون فقط ، على سبيل المثال ، الأوامر التي يتم تنفيذها كما هو متوقع من shell ولكن يتم تنفيذها بطريقة خاطئة بواسطة cron.


455


الأصل


يجب أن تغلق crontab -e لكي يتم تفعيلها. على سبيل المثال باستخدام vim يمكنني تحرير الملف واستخدامه :w لكتابة ولكن لم يتم إضافة الوظيفة إلى cron حتى استقال أنا أيضا. لذلك لن أرى العمل حتى بعد :q أيضا. - DutGRIFF
أعتقد أن أفضل طريقة لتصحيح cron هي التحقق من syslog والعثور على المشاكل. - Suneel Kumar
في حالتي - كان البريد الإلكتروني يذهب إلى مجلد الرسائل الاقتحامية (SPAM) الخاص بي ، لذلك ..... تأكد من أنك قبل قضاء ساعات في تصحيح الأخطاء: D - almaruf
انقطاع الكهرباء - Josef Klimuk


الأجوبة:


بيئة مختلفة

يمر Cron بمجموعة صغيرة من متغيرات البيئة لوظائفك. لمعرفة الفرق ، أضف وظيفة وهمية مثل هذا:

* * * * * env> /tmp/env.output

أنتظر لأجل /tmp/env.output ليتم إنشاؤه ، ثم قم بإزالة المهمة مرة أخرى. الآن مقارنة محتويات /tmp/env.output مع ناتج env تشغيل في محطة الخاص بك العادية.

مشترك "مسكتك" هنا هو PATH متغير البيئة يجري مختلفة. ربما يستخدم البرنامج النصي الخاص بك cron الأمر somecommand عثر عليه في /opt/someApp/binالتي أضفتها إلى PATH في /etc/environment؟ كرون يتجاهل PATH من هذا الملف ، لذلك runnning somecommand من البرنامج النصي الخاص بك سوف تفشل عند تشغيل مع cron ، ولكن العمل عند تشغيل في المحطة. تجدر الإشارة إلى أن المتغيرات من /etc/environment سيتم تمريرها إلى وظائف cron ، فقط لا المتغيرات cron يحدد نفسه بشكل محدد ، مثل PATH.

للالتفاف على ذلك ، فقط تعيين الخاصة بك PATH متغير في الجزء العلوي من البرنامج النصي. مثلا

#!/bin/bash
PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# rest of script follows

البعض يفضل فقط استخدام المسارات المطلقة لجميع الأوامر بدلا من ذلك. أوصي ضد ذلك. ضع في اعتبارك ما يحدث إذا كنت ترغب في تشغيل البرنامج النصي الخاص بك على نظام مختلف ، وفي هذا النظام ، يكون الأمر موجودًا /opt/someAppv2.2/bin في حين أن. سيكون عليك الذهاب من خلال استبدال النص بأكمله /opt/someApp/bin مع /opt/someAppv2.2/bin بدلاً من إجراء تعديل صغير على السطر الأول من النص البرمجي.

يمكنك أيضًا تعيين متغير PATH في ملف crontab ، والذي سينطبق على جميع مهام cron. مثلا

PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

15 1 * * * backupscript --incremental /home /root

431



أعتقد أنني وقعت للتو لهذا ، وخط جديد في النهاية ... الضجة المزدوجة. - WernerCD
+1 لـ env، لقد نسيت تماما عن هذا الأمر وفكرت PATH كان يعمل. كان في الواقع sliiiightly مختلفة في حالتي. - Izkata
@ pbr إذا تم ترك هذه الدلائل قابلة للكتابة للآخرين ، فسيتم اختراق النظام بالفعل. - geirha
pbr A sysadmin يمكن أن يحذف نظام الملفات الجذر بدون قصد. لا يمكنك الحراسة ضد sysadmins جعل أخطاء سخيفة. إذا قمت بتثبيت إصدار أحدث من مترجم غير متوافق مع الإصدارات السابقة ، فسوف أتوقع حدوث كسر بغض النظر. الطريقة المعقولة للتعامل مع ذلك هي تثبيته كأمر مختلف. مثلا لديك الإصدار 2.x python وتثبيته python 3 ، يمكنك تثبيته كـ python3 ، وليس python. أما بالنسبة لـ / opt / someApp / bin ، فلماذا على الأرض ليس لديها أذونات / ملكية معقولة؟ أي مسؤول عاقل سوف يضمن أذونات عاقل / ملكية على ملفات النظام. - geirha
@ pbr يبدو أننا يمكن أن تستمر إلى الأبد ، نعم. ما زلت لا أرى لماذا هو فكرة سيئة لاستخدام PATH على الرغم من. إذا كنت ترغب في مناقشة هذا الأمر بشكل أكبر في وسيط أكثر ملاءمة للمناقشة ، فستجدني في #ubuntu و #bash ، من بين قنوات أخرى ، على irc.freenode.net - geirha


بلدي أعلى مسكتك: إذا نسيت أن تضيف سطر جديد في نهاية crontab ملف. بمعنى آخر ، يجب أن ينتهي ملف crontab بخط فارغ.

في ما يلي القسم ذو الصلة في صفحات الرجل لهذه المشكلة (man crontab ثم انتقل إلى النهاية):

   Although cron requires that each entry in a crontab end  in  a  newline
   character,  neither the crontab command nor the cron daemon will detect
   this error. Instead, the crontab will appear to load normally. However,
   the  command  will  never  run.  The best choice is to ensure that your
   crontab has a blank line at the end.

   4th Berkeley Distribution      29 December 1993               CRONTAB(1)

291



هذا هو showstopper ، فكيف لم يتم إصلاحه في سنوات عديدة من cron؟ - Capi Etheriel
يبدو أن تكون ثابتة في Vixie كرون: man crontab على Ubuntu 10.10 يقول "cron يتطلب أن كل إدخال في نهاية crontab في حرف السطر الجديد. إذا كان آخر إدخال في crontab يفتقد السطر الجديد ، سوف يفكر cron crontab (على الأقل جزئيًا) مكسور ويرفض تثبيته." (والتاريخ في النهاية هو 19 أبريل 2010.) - Marius Gedminas
barraponto هذا بالفعل خطأ في برامج تحرير النصوص الجديدة. من المفترض أن يكون الحرف "newline" هو إنهاء الخط لذلك ، من المفترض أن ينتهي السطر الأخير في ملف نصي بحرف السطر الجديد الذي لا يظهر في المحرر. استخدم Vi و vim الحرف بشكل صحيح ، وتم بناء cron قبل أن يبدأ المحررين الجدد سلوكهم الغريب ... ومن ثم لعب حفظه ويتضمن سطرًا فارغًا. - Izkata
إذا قمت بتحرير crontab باستخدام crontab -e سيتحقق من صيغة الملف قبل السماح بالحفظ ، بما في ذلك التحقق من سطر جديد. - Tom Harrison Jr
@ Chan-HoSuh ، وفقا لصفحة رجل "cron يتطلب أن كل إدخال في نهاية crontab في حرف السطر الجديد. إذا كان آخر إدخال في crontab يفتقد السطر الجديد ، سوف تنظر كرون في crontab (على الأقل جزئيا) مكسورة وترفض تثبيته ". سيتم استدعاء هذا السلوك عند التحرير ثم حفظ crontab باستخدام -e الخيار ، ومستقل عن المحرر. - Tom Harrison Jr


Cron daemon ليس قيد التشغيل. أنا حقا ثمل مع هذا منذ بضعة أشهر.

اكتب:

pgrep cron 

إذا لم ترى أي رقم ، فلن يتم تشغيل cron. sudo /etc/init.d/cron start يمكن استخدامها لبدء cron.

تحرير: بدلاً من استدعاء البرامج النصية init خلال /etc/init.d ، استخدم الخدمة فائدة ، على سبيل المثال

sudo service cron start

125



شكرا لتظهر لي pgrep. ظللت به ps -ef | grep foo - ripper234
يمكنك أيضا استخدام pidof cron والذي سيؤدي إلى حذف النتائج للتطبيقات الأخرى التي تحتوي أيضًا على كلمة "cron" ، مثل crontab. - Pithikos
غريب ، كل هذه لا تعطيني أي شيء لإظهار كرون قيد التشغيل ، ولكن إذا قمت بتشغيل sudo service cron start انا حصلت start: Job is already running: cron - Colleen
service crond start إذا كان centos / RHEL - Srihari Karanth


اسم الملف النصي في cron.d/، cron.daily/، cron.hourly/، وما إلى ذلك ، يجب ألا يحتوي على نقطة (.) ، وإلا سيتم تخطي أجزاء التشغيل.

انظر تشغيل أجزاء (8):

   If neither the --lsbsysinit option nor the --regex option is given then
   the names must consist entirely of upper and lower case  letters,  dig‐
   its, underscores, and hyphens.

   If  the  --lsbsysinit  option  is given, then the names must not end in
   .dpkg-old  or .dpkg-dist or .dpkg-new or .dpkg-tmp, and must belong  to
   one  or more of the following namespaces: the LANANA-assigned namespace
   (^[a-z0-9]+$);   the   LSB   hierarchical   and   reserved   namespaces
   (^_?([a-z0-9_.]+-)+[a-z0-9]+$);  and  the  Debian cron script namespace
   (^[a-zA-Z0-9_-]+$).

لذا ، إذا كان لديك برنامج نصي cron backup.sh، analyze-logs.pl في cron.daily/ الدليل ، من الأفضل إزالة أسماء الإضافة.


83



انها ميزة لا علة - انها تحافظ على أشياء مثل myscript.backup أو myscript.original أو myscript.rpm-new من تشغيل الحق بجانب myscript. - pbr
@ ص ب: من المنطقي. على الأقل كان من المفيد لتصحيح الأخطاء إذا run-parts --test (أو خيار خيالي آخر مثل --debug سوف تخرج الملفات التي يتخطى بها السبب. - Rabarberski
إذا كانت هذه ميزة ، فهي ليست ميزة جيدة :( يستخدم الكثير من الأشخاص نقطة في اسم الملف (backup.sh هو الأكثر شيوعًا). إذا أردت أن يتوقف أحد البرامج النصية عن التنفيذ ، فإن الطريقة الأكثر منطقية هي إزالته من دليل "cron.d". - MatuDuke
هذه هي ميزة سيئة أنها بقة. من الشائع أن تتطلب نهاية معينة (مثل ".list" أو ".cron" أو أي شيء آخر) إذا أراد الأشخاص التأكد من أن الأشياء لا تعمل إلا عندما تكون مقصودة. اختيار نقطة عشوائية على أنها فاصل محتمل لـ ".bak" أو ".temp" أو أيًا كان ، لا يمكن التنبؤ به تمامًا باستثناء الطريقة التي تؤدي إلى إرباك الأشخاص. النهايات الشرعية مثل ".sh" ، و ".pl" استخدمت على نطاق واسع منذ عقود. يستخدم الكثير من الأشخاص "_bak" أو "_temp" أو "-bak" بدلاً من نقطة. هذا هو اختيار تصميم فظيعة. انها علة تصميم في أحسن الأحوال. - Teekin


في العديد من البيئات cron تنفيذ الأوامر باستخدام sh، في حين يفترض كثير من الناس أنها سوف تستخدم bash.

اقتراحات لاختبار أو إصلاح ذلك لأمر فاشل:

  • حاول تشغيل الأمر في sh لمعرفة ما إذا كان يعمل
  • لف الأمر في subshell bash للتأكد من تشغيله في bash:
    bash -c "mybashcommand"
  • أخبر cron بتشغيل جميع الأوامر في bash عن طريق تعيين shell في أعلى crontab:
    SHELL=/bin/bash
  • إذا كان الأمر نصًا ، فتأكد من احتواء البرنامج النصي على مفتاح:
    #!/bin/bash

55



اقتراح باش مفيد جدا، قضية ثابتة مع بلدي كرون. - Maxim Galushka
هذا تسبب لي فقط 1 ساعة من تافه / استكشاف الأخطاء وإصلاحها. حتى أكثر تعقيدا إذا لم تكن على علم بالمشكلة ، فسيتم تشغيل النص البرمجي يدويًا بشكل جيد إذا كنت تستخدم shell النموذجي bashولكن ليس مع cron. شكر! - Hendy
منذ فترة طويلة ، واجهت شيئًا ذا صلة: الأمر source في bash لكن ليس sh. في cron / sh ، استخدم نقطة: . envfile بدلا من source envfile. - kungphu


كان لدي بعض المشاكل مع المناطق الزمنية. كان يعمل Cron مع المنطقة الزمنية التثبيت الطازجة. كان الحل هو إعادة تشغيل cron:

sudo service cron restart

34



نعم ، بعد تغيير المنطقة الزمنية على أحد الأنظمة ، يجب على الشخص إما إعادة تشغيل كل خدمة تهتم بالوقت أو إعادة التشغيل. أنا أفضل إعادة التشغيل ، للتأكد من أنني اشتعلت كل شيء. - pbr
يا لله ، قتلت ساعات على هذا. إعادة تشغيل الخدمة بعد * * * * * touch /tmp/cronworks لم يفعل شيئا ، ولكن هناك RELOAD في cronlog. - НЛО


إذا كان الأمر crontab الخاص بك لديه % رمز في ذلك ، يحاول cron تفسيره. حتى إذا كنت تستخدم أي قيادة مع % في ذلك (مثل مواصفات تنسيق الأمر التاريخ) سوف تحتاج إلى الهروب منه.

هذا وأشياء أخرى جيدة هنا:
http://www.pantz.org/software/cron/croninfo.html


29



هذا ما تسبب في فشل مهمة Cron الخاصة بي في الأسبوع الماضي. وأخيرا برزت أن التاريخ الخاص بي لم يكن لديه حرف هروب (خط مائل عكسي لأي أشخاص آخرين يبحثون عن ما هو حرف الهروب). ياي! - Valien
أنظر أيضا كيف يمكنني التنفيذ date داخل وظيفة علامة التبويب كرون؟ - Jared Beck
هذا واحد لي أيضا. شكر! - stefansundin


يجب استخدام المسار المطلق للنصوص البرمجية:

فمثلا، /bin/grep ينبغي أن تستخدم بدلا من grep:

# m h  dom mon dow   command
0 0 *  *  *  /bin/grep ERROR /home/adam/run.log &> /tmp/errors

بدلا من:

# m h  dom mon dow   command
0 0 *  *  *  grep ERROR /home/adam/run.log &> /tmp/errors

هذا أمر صعب خاصة ، لأن نفس الأمر سيعمل عند تنفيذه من الصدفة. والسبب هو أن cron ليس لديه نفس الشيء PATH متغير البيئة كمستخدم.


28



انظر geirha الإجابة ، يمكنك (يجب) تعريف PATH cron - Capi Etheriel
Bzzt. لا تحتاج إلى تعريف PATH - استخدام المسارات المطلقة هو أفضل الممارسات هنا. "لأن الملف التنفيذي قد يكون في مكان آخر على بعض أجهزة الكمبيوتر الأخرى" لا تتفوق "أريده أن يعمل بالضبط هذا البرنامج وليس شخص آخر وضعه في المسار أمام البرنامج الأصلي" - pbr
نعم هذا كان بالنسبة لي ، خارج cron يمكنني تشغيل الأمر مباشرة ، داخل cron يحتاجها الكامل /usr/bin/whatever مسار - Anentropic


من الممكن أيضًا أن تكون كلمة مرور المستخدم منتهية الصلاحية. حتى كلمة مرور الجذر يمكن أن تنتهي. تستطيع tail -f /var/log/cron.log وسترى cron fail مع انتهاء صلاحية كلمة المرور. يمكنك تعيين كلمة المرور بحيث لا تنتهي صلاحيتها أبدًا عن طريق القيام بذلك: passwd -x -1 <username>

في بعض الأنظمة (Debian، Ubuntu) لا يتم تمكين تسجيل الدخول إلى cron بشكل افتراضي. في /etc/rsyslog.conf أو /etc/rsyslog.d/50-default.conf الخط:

# cron.*                          /var/log/cron.log

يجب تحريره (sudo nano /etc/rsyslog.confغير مقيد إلى:

cron.*                          /var/log/cron.log

بعد ذلك ، تحتاج إلى إعادة تشغيل rsyslog عبر

/etc/init.d/rsyslog restart

أو

service rsyslog restart 

مصدر: تمكين تسجيل crontab في Debian Linux

في بعض الأنظمة (Ubuntu) لا يتم تمكين ملف التسجيل المنفصل لـ cron بشكل افتراضي ، ولكن سجلات cron المتعلقة تظهر في ملف syslog. يمكن للمرء أن يستخدم

cat /var/log/syslog | grep cron

لعرض الرسائل المتعلقة بالكرون.


23



لدي Debian (wheezy) ولكن لا يوجد /etc/init.d/rsyslog ، فقط inetutils-syslogd و sysklogd. هل يجب علي تثبيت شيء ما أو إعادة تشغيل أحدهما؟ - hgoebl


يدعو Cron برنامج نصي غير قابل للتنفيذ.

عن طريق الركض chmod +x /path/to/scrip يصبح البرنامج النصي قابل للتنفيذ ويجب حل هذه المشكلة.


21



هذا ليس فريد من نوعه ل cron، ويمكن عزوها بسهولة بمجرد محاولة التنفيذ /path/to/script من سطر الأوامر. - Adam Matan
إذا كنت معتادًا على تنفيذ النصوص البرمجية مع . scriptname أو sh scriptname أو bash scriptname، ثم يصبح هذا cronمشكلة محددة. - Eliah Kagan


إذا كانت cronjob تستدعي تطبيقات واجهة المستخدم الرسومية ، فستحتاج إلى إخبارهم بما يجب عليهم استخدام DISPLAY.

مثال: إطلاق Firefox مع cron.

يجب أن يحتوي البرنامج النصي الخاص بك export DISPLAY=:0 مكان ما.


16



احتاج aplay هذا واحد لسبب ما. شكرا - IljaBek
* * * * * export DISPLAY=:0 && <command> - LoMaPh