Чому сценарії crontab не працюють?


525

Часто crontabсценарії виконуються не за розкладом або як очікувалося. Для цього є численні причини:

  1. неправильне позначення crontab
  2. проблема дозволів
  3. змінні середовища

Ця вікі спільноти має на меті об'єднати основні причини того, що crontabсценарії не виконуються, як очікувалося. Запишіть кожну причину в окрему відповідь.

Будь ласка, включіть одну причину на відповідь - детальну інформацію про те, чому вона не виконується - та виправлення (і) з цієї причини.

Будь ласка, напишіть лише проблеми, пов’язані з кроном, наприклад команди, які виконуються, як очікувалося від оболонки, але виконують помилково за допомогою cron.


12
Ви повинні закрити, crontab -eщоб крон впливав. Наприклад, використовуючи vim, я редагую файл і використовую :wдля його запису, але завдання не додається в cron, поки я також не вийду. Тому я не буду бачити роботу до того, як я :qтеж.
DutGRIFF

Я думаю, що найкращий спосіб налагодити cron - це перевірити syslog та знайти проблеми.
Suneel Kumar

У моєму випадку - повідомлення електронної пошти переходило до моєї папки СПАМ, тому ..... переконайтеся, що перш ніж витратити години на налагодження: D
almaruf

Відключення електроенергії
Йозеф Климук

Відповіді:


501

Різне середовище

Cron передає мінімальний набір змінних оточуючих до ваших завдань. Щоб побачити різницю, додайте подібну роботу:

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

Дочекайтеся /tmp/env.outputстворення, а потім видаліть завдання знову. Тепер порівняйте вміст /tmp/env.outputз результатом envзапуску у вашому звичайному терміналі.

Поширена тут "gotcha" - це те, що PATHзмінна середовища є різною. Може бути , ваш хрон сценарій використовує команду somecommandзнайдену в /opt/someApp/bin, який ви додали PATHв /etc/environment? cron ігнорує PATHцей файл, тому 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

5
Я думаю, що я просто потрапив за це, і новий рядок в кінці ... подвійний бомж.
WernerCD

6
+1 для env, я зовсім забув про цю команду і подумав, що PATH працює. Насправді в моєму випадку це було зовсім інше.
Ізката

8
@pbr Якщо такі каталоги залишені для запису для інших, система вже порушена.
geirha

6
@pbr Система sysadmin може мимоволі видалити кореневу файлову систему. Ви не можете захиститись від сисадмінів, які роблять дурні помилки. Якщо ви встановите новішу версію інтерпретатора, яка не сумісна назад, я б очікував поломки незалежно. Раціональний спосіб впоратися з цим - це встановити його як іншу команду. Наприклад, у вас є версія python 2.x та встановлено python 3, ви встановлюєте його як python3, а не python. А що стосується / opt / someApp / bin, то чому б на землі він не мав би дозволених прав / прав власності? будь-який здоровий адміністратор забезпечить нормальні дозволи / право власності на файли системи.
geirha

2
@pbr Здається, ми могли б продовжуватись назавжди, так. Я все ще не розумію, чому це погана ідея використовувати PATH, хоча. Якщо ви захочете обговорити це далі в середовищі, що підходить для обговорення, ви знайдете мене в #ubuntu та #bash, серед інших каналів, на irc.freenode.net
geirha

336

Моя головна робота: Якщо ви забудете додати новий рядок в кінці 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)

91
це такий шоустоппер, як це не було зафіксовано за стільки років крону?
Capi Etheriel

2
Здається, виправлено в Cron Vixie: man crontabв Ubuntu 10.10 сказано, що "cron вимагає, щоб кожен запис у crontab закінчувався символом нового рядка. Якщо в останньому записі в crontab відсутній новий рядок, cron вважає, що crontab (принаймні частково) зламаний і відмовитись його встановлювати ". (А дата в кінці - 19 квітня 2010 р.)
Маріус Гедмінас

19
@barraponto Це фактично помилка в нових текстових редакторах. Символ "нового рядка" повинен бути символом завершення рядка , тому завершальний рядок у текстовому файлі повинен закінчуватися символом нової лінії, який не відображається в редакторі. Vi і vim правильно використовують цей символ, а cron був побудований до того, як нові редактори почали свою дивну поведінку ... Отже, граючи в нього, зберігайте та включаючи порожній рядок.
Ізката

6
Якщо ви редагуєте crontab за допомогою crontab -eнього, він перевірятиме синтаксис файлу перед тим, як дозволити збереження, включаючи перевірку на новий рядок.
Том Гаррісон-молодший

2
@ Chan-HoSuh, згідно зі сторінкою людини "cron вимагає, щоб кожен запис у crontab закінчувався новим рядком. Якщо в останньому записі в crontab відсутній новий рядок, cron вважає, що crontab (принаймні частково) зламаний, і відмовиться від встановіть його. " Ця поведінка буде викликатись під час редагування, а потім збереження crontab за допомогою -eпараметра, і не залежить від редактора.
Том Гаррісон-молодший

139

Демон Крона не працює. Я справді накрутив це кілька місяців тому.

Тип:

pgrep cron 

Якщо ви не бачите жодного номера, то cron не працює. sudo /etc/init.d/cron startможна використовувати для запуску крона.

EDIT: Замість того, щоб викликати скрипти init через /etc/init.d, використовуйте службову утиліту, наприклад

sudo service cron start

EDIT: Також ви можете використовувати systemctl в сучасному Linux, наприклад

sudo systemctl start cron

47
Дякуємо, що показали мені pgrep. Я продовжував робити ps -ef | grep foo
ripper234

4
Ви також можете використовувати результати, pidof cronякі опускають результати для інших програм, які також мають слово "cron", як crontab.
Пітікос

Дивно, всі вони не дають мені нічого, щоб показати, що cron працює, але якщо я біжу, sudo service cron startя отримуюstart: Job is already running: cron
Colleen

1
service crond startякщо його центос / RHEL
Шріхарі Карант

91

Сценарій для імен файлів в 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/каталозі вам найкраще видалити імена розширень.


10
Це особливість, а не помилка - вона захищає такі речі, як myscript.backup або myscript.original або myscript.rpm-new, які працюють безпосередньо біля myscript.
пбр

@pbr: має сенс. Принаймні, це було б корисно для налагодження, якщо run-parts --test(або інший уявний варіант, як-от --debugвиводить файли, які він пропускає, включаючи причину.
Rabarberski

8
Якщо це функція, це не дуже приємно :( Багато людей використовують крапку в імені файлу (backup.sh - найпоширеніший). Якщо ви хочете, щоб сценарій припинив виконання, найбільш логічним методом буде видаліть його з каталогу "cron.d".
MatuDuke

7
Це настільки погана особливість, що це фактично помилка. Поширена практика вимагає конкретного закінчення (наприклад, ".list" або ".cron" чи чогось іншого), якщо люди хочуть переконатися, що все працює лише за призначенням. Довільно вибирати крапку як імовірний роздільник для ".bak" або ".temp" чи будь-чого іншого, абсолютно непередбачувано, за винятком того, що воно передбачувано заплутає людей. Узаконені закінчення на зразок ".sh" та ".pl" широко використовуються протягом десятиліть. Однак багато людей використовують "_bak" або "_temp" або "-bak" замість крапки. Це жахливий вибір дизайну; це помилка в дизайні в кращому випадку.
Текін

68

У багатьох середовищах cron виконує команди, використовуючи sh, тоді як багато людей припускають, що це використовуватиме bash.

Пропозиції перевірити або виправити це за невдалою командою:

  • Спробуйте запустити команду, shщоб побачити, чи працює вона:

    sh -c "mycommand"
    
  • Загорніть команду в нижню частину bash, щоб переконатися, що вона запускається в bash:

    bash -c "mybashcommand"
    
  • Скажіть cron виконувати всі команди в bash, встановивши оболонку вгорі вашої crontab:

    SHELL=/bin/bash
    
  • Якщо команда є сценарієм, переконайтеся, що сценарій містить шебанг:

    #!/bin/bash
    

Баш пропозиція дуже корисна, виправлена ​​проблема з моїм кроном.
Максим Галушка

Це щойно викликало у мене 1 годину нескінченності / усунення несправностей. Ще більше здивування, якщо ви не знаєте про проблему, це те, що сценарій буде працювати вручну просто чудово, якщо ти типова оболонка bash, але не з cron. Дякую!
Генді

Давно я зіткнувся з чимось пов’язаним: Команда sourceв баш, але не в ш. У cron / sh використовуйте період: . envfileа не source envfile.
kungphu

@Clockwork sh "mycommand"повідомляє shзапустити mycommand як файл сценарію. Ви мали на увазі sh -c "mycommand"? У будь-якому випадку ця відповідь, мабуть, стосується того, щоб команда запускалася в bash спеціально, так чому ви тут додали команду sh?
Олорін

@Olorin З мого розуміння, метою першого пункту було спробувати запустити його з sh, щоб побачити, чи справді проблема виникла з того, що cron працює з sh замість bash. Тоді знову я мало знаю про цю справу, тому я можу помилитися.
Годинник

39

У мене були деякі проблеми з часовими поясами. Cron працював зі свіжим часовим поясом. Рішенням було перезапустити cron:

sudo service cron restart

6
Так, після зміни часового поясу в системі потрібно або перезапустити кожну службу, яка піклується про час, або перезавантажити. Я вважаю за краще перезавантаження, щоб бути впевненим, що я все зловив.
пбр

Боже заради Бога, вбивали на це години. Перепробуваний сервіс перезапустив після того, * * * * * touch /tmp/cronworksяк нічого не зробив, все ж є RELOADв cronlog.
НЛО

36

Для сценаріїв слід використовувати абсолютний шлях:

Наприклад, /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змінної середовища, що і користувач.


3
дивіться відповідь geirha, ви можете (обов'язково) визначити PATH cron
Capi Etheriel

9
Bzzt. НЕ потрібно визначати PATH - використання абсолютних шляхів є найкращою практикою тут. "тому що виконуваний файл може бути в іншому місці на якомусь іншому комп'ютері" не козир "Я хочу, щоб він запускав саме цю програму, а не якийсь інший, кого хтось поставив на шляху перед моєю початковою програмою"
пбр

1
так, це було для мене, поза кроном я міг би запускати команду безпосередньо, всередині /usr/bin/whatever
крона

32

Якщо ваша команда crontab містить %символ, cron намагається її інтерпретувати. Отже, якщо ви використовували будь-яку команду з командою a %(наприклад, специфікація формату до команди date), вам потрібно буде залишити її.

Це та інші хороші сюди:
http://www.pantz.org/software/cron/croninfo.html


Це те, що спричиняє збій моєї роботи Cron за останній тиждень. Нарешті з’ясував, що в моїй Даті немає символу втечі (зворотний косий рядок для інших людей, які шукають, що таке символ втечі). Так!
Вальєн


25

Cron викликає сценарій, який не виконується.

Запуск chmod +x /path/to/scripсценарію стає виконуваним і має вирішити цю проблему.


5
Це не властиво cronі легко простежується, просто намагаючись виконати /path/to/scriptз командного рядка.
Адам Матан

4
Якщо ви звикли виконувати скрипти з . scriptnameабо sh scriptnameабо bash scriptname, то це стає cronспецифічною проблемою.
Елія Каган

24

Можливо також, що термін дії пароля користувача закінчився. Навіть пароль root може закінчитися. Ви можете, tail -f /var/log/cron.logі ви побачите невдачу cron із минулим паролем. Ви можете встановити пароль, щоб ніколи не закінчувався термін дії: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 

Джерело: Увімкніть ведення журналу через клітки в Debian Linux

У деяких системах (Ubuntu) окремий файл журналу для cron за замовчуванням не вмикається, але журнали, пов’язані з cron, відображаються у файлі syslog. Можна використовувати

cat /var/log/syslog | grep cron -i

для перегляду повідомлень, пов’язаних з хроном.


У мене є Debian (wheezy), але немає /etc/init.d/rsyslog, лише inetutils-syslogd і sysklogd. Потрібно щось встановити чи просто перезапустити одне з двох?
hgoebl

18

Якщо ваш cronjob викликає GUI-додатки, вам потрібно сказати їм, що DISPLAY вони повинні використовувати.

Приклад: запуск Firefox з кроном.

Ваш сценарій повинен export DISPLAY=:0десь містити .


Аплей знадобився цьому чомусь. дякую
IljaBek

* * * * * export DISPLAY=:0 && <command>
LoMaPh

15

Боюся, проблеми з дозволом є досить поширеними.

Зауважте, що поширене вирішення полягає у виконанні всього за допомогою crontab root, що іноді є дійсно поганою ідеєю. Налаштування належних дозволів, безумовно, є значною мірою недоотриманою проблемою.


Зауважте, що якщо у вас є лінія crontab, яка встановлена ​​для виведення труб у файл, який ще не існує, а каталог для файлу такий, до якого користувач cron не має доступу, то ця лінія не буде виконуватися.
Еван Донован

14

Небезпечний дозвіл на таблицю cron

Таблиця cron відхиляється, якщо її дозвіл є незахищеним

sudo service cron restart
grep -i cron /var/log/syslog|tail -2
2013-02-05T03:47:49.283841+01:00 ubuntu cron[49906]: (user) INSECURE MODE (mode 0600 expected) (crontabs/user)

Проблема вирішена с

# correct permission
sudo chmod 600 /var/spool/cron/crontabs/user
# signal crond to reload the file
sudo touch /var/spool/cron/crontabs

Спочатку я сам це зрозумів, а потім знайшов вашу відповідь! Ще велике спасибі! У моєму випадку я повернув / відновив кілька crontabs у / var / spool / cron / crontabs через SVN, який змінив його дозволи!
alfonx

12

Сценарій чутливий до місця розташування. Це пов’язано з тим, що завжди використовувати абсолютний шлях у сценарії, але не зовсім однаково. cdПеред тим, як запустити роботу cron, потрібно запустити певний каталог перед запуском, наприклад, завдання Rake для програми Rails може знадобитися в корені програми для Rake, щоб знайти правильну задачу, не кажучи вже про відповідну конфігурацію бази даних тощо.

Отже, запис на кронтаб

23 3 * * * /usr/bin/rake db:session_purge RAILS_ENV=production

було б краще як

23 3 * * * cd / var / www / production / current && / usr / bin / rake db: session_purge RAILS_ENV = виробництво

Або, щоб зробити запис на кронтабі простішим і менш крихким:

23 3 * * * /home/<user>/scripts/session-purge.sh

із наступним кодом у /home/<user>/scripts/session-purge.sh:

cd / var / www / виробництво / поточний
/ usr / bin / rake db: session_purge RAILS_ENV = виробництво

1
Якщо сценарій, на який посилається cron, написаний на інтерпретованій мові, як PHP, можливо, вам доведеться встановити робочий каталог у самому сценарії. Наприклад, в PHP: chdir(dirname(__FILE__));
Еван Донован,

Щойно зациклювався на цьому: сценарій був у корені мого домашнього каталогу, але потім я перемістив його (і оновив crontab) і не міг зрозуміти, чому він не працює. Виявляється, сценарій використовував відносний шлях, припускаючи, що він був відносно місця розташування скрипту, але насправді був відносно кореня мого домашнього каталогу, оскільки це був робочий каталог, який використовувався cron, і саме тому сценарій працював , коли він був в корені домашнього каталогу (так як очікується , робочий каталог скрипта , і це фактичне робоче просто трапилося збігтися).
Мішель Джонсон

11

Специфікації Crontab, які працювали в минулому, можуть зламатися при переміщенні з одного файлу crontab в інший. Іноді причина полягає в тому, що ви перемістили специфікацію з системного файлу crontab в файл користувача crontab або навпаки.

Формат специфікації завдання cron відрізняється між файлами crontab користувачів (/ var / spool / cron / username або / var / spool / cron / crontabs / username) та системними crontabs ( /etc/crontabта файлами в /etc/cron.d).

У системних crontabs є додаткове поле 'user' безпосередньо перед командою для запуску.

Це призведе до помилок із зазначенням таких речей, як, наприклад, george; command not foundколи ви переміщуєте команду з /etc/crontabабо в файл у /etc/cron.dфайлі crontab користувача.

І навпаки, cron доставить помилки, подібні /usr/bin/restartxyz is not a valid usernameабо подібні, коли відбувається зворотний зв'язок.


10

cron script викликає команду з опцією --verbose

У мене вийшов з ладу сценарій cron, оскільки я був на автопілоті під час введення сценарію, і я включив варіант --verbose:

#!/bin/bash
some commands
tar cvfz /my/archive/file.tar.gz /my/shared/directory
come more commands

При виконанні з оболонки сценарій чудово спрацьовував, але не вдався при запуску з crontab, оскільки багатослівний висновок переходить до stdout при запуску з оболонки, але нікуди при запуску з crontab. Просте виправлення, щоб видалити 'v':

#!/bin/bash
some commands
tar cfz /my/archive/file.tar.gz /my/shared/directory
some more commands

5
Чому це викликає збій? Проблеми з буфером?
Адам Матан

Будь-які виходи або помилки trriggred через Хроні робочих місць є gooing посланого до вашого mailbox.So ми ніколи не повинні забувати піклуватися про ці помилки / output.We може перенаправити їх в будь-який файл або / Dev / нуль
Nischay

10

Найчастіша причина, коли я бачив, як крон виходить з ладу в неправильно зазначеному графіку. Треба визначати роботу, заплановану на 23:15, 15 23 * * *замість * * 11 15 *або 11 15 * * *. День тижня для робочих місць після півночі також плутається MF - це 2-6після півночі, ні 1-5. Конкретні дати зазвичай є проблемою, оскільки ми рідко їх використовуємо * * 3 1 *не 3 березня. Якщо ви не впевнені, перевірте свої графіки роботи в Інтернеті за адресою https://crontab.guru/ .

Якщо ваша робота з різними платформами, що використовують непідтримувані параметри, такі як 2/3часові специфікації, також може спричинити збої. Це дуже корисний варіант, але не доступний повсюдно. Я також стикався з проблемами зі списками, як 1-5або 1,3,5.

Використання некваліфікованих шляхів також спричинило проблеми. Шлях за замовчуванням зазвичай, /bin:/usr/binтому виконуватимуться лише стандартні команди. Ці каталоги зазвичай не мають потрібної команди. Це також впливає на сценарії, що використовують нестандартні команди. Інші змінні середовища також можуть бути відсутніми.

Знебарвлення наявного кронтабу повністю викликало у мене проблеми. Тепер завантажую з копії файлу. Це можна відновити з існуючого кронтабу, використовуючи, crontab -lякщо він стає клоберованим. Я зберігаю копію crontab у ~ / bin. Він коментується по всьому і закінчується рядком # EOF. Це щодня перезавантажується із запису на кронтабній версії, наприклад:

#! / usr / bin / crontab
# Перезавантажте цей кронтаб
#
54 12 * * * $ {HOME} / bin / crontab

Команда перезавантаження вище покладається на виконуваний crontab з нарізною ланкою, що працює під керуванням crontab. Деякі системи вимагають запуску crontab у команді та вказівці файлу. Якщо каталог загальнодоступним, я часто використовую crontab.$(hostname)як ім'я файлу. Це врешті виправить випадки, коли неправильний crontab завантажується на неправильний сервер.

Використання файлу забезпечує резервну копію того, що має бути crontab, і дозволяє тимчасові зміни (єдиний раз, коли я використовую crontab -e), резервне копіювання автоматично. Існують заголовки, які допомагають правильно встановити параметри планування. Я додав їх, коли недосвідчені користувачі редагували б кронтаб.

Рідко я стикаюся з командами, які потребують введення користувача. Вони не спрацьовують під crontab, хоча деякі працюватимуть із перенаправленням вводу.


3
Це охоплює три окремі проблеми. Чи можна їх розділити на окремі відповіді?
Елія Каган

9
Чи можете ви пояснити, як 30 23 * * * перекладається до 23:15?
JYelton

@JYelton Це, очевидно, було неправильно 15 23 * * *. Виправлено зараз.
Мелебій

7

Якщо ви отримуєте доступ до облікового запису за допомогою SSH-ключів, ви можете увійти в обліковий запис, але не помітити, що пароль в обліковому записі заблокований (наприклад, через закінчення терміну чи недійсних спроб пароля)

Якщо система використовує PAM, а обліковий запис заблоковано, це може зупинити її роботу. (Я тестував це на Solaris, але не на Ubuntu)

Ви можете знайти такі повідомлення в / var / adm / messages:

24 жовтня 07:51:00 mybox cron [29024]: [ID 731128 auth.notice] pam_unix_account: cron намагається перевірити заблокований обліковий запис myuser від локального хоста
24 жовтня 07:52:00 mybox cron [29063]: [ID 731128 auth.notice] pam_unix_account: cron намагається перевірити заблокований обліковий запис myuser від локального хоста
24 жовтня 07:53:00 mybox cron [29098]: [ID 731128 auth.notice] pam_unix_account: cron намагається перевірити заблокований обліковий запис myuser від місцевого хоста
24 жовтня 07:54:00 mybox cron [29527]: [ID 731128 auth.notice] pam_unix_account: cron намагається перевірити заблокований обліковий запис myuser від місцевого хоста

Все, що вам потрібно зробити, це запустити:

# passwd -u <USERNAME>

як root, щоб розблокувати обліковий запис, і crontab повинен працювати знову.


7

Якщо у вас є така команда:

* * * * * /path/to/script >> /tmp/output

і він не працює, і ви не бачите жодного виводу, це не обов'язково означає, що cron не працює. Сценарій може бути порушений, і висновок буде stderr, який не передається в / tmp / output. Перевірте це не так, захопивши і цей вихід:

* * * * * /path/to/script >> /tmp/output 2>&1

щоб дізнатися, чи це допоможе вам зрозуміти свою проблему.


3

=== Сповіщення про докер ===

Якщо ви використовуєте докер,

Я думаю, що правильно додати, що мені не вдалося змусити змусити cron працювати у фоновому режимі.

Щоб запустити роботу cron всередині контейнера, я застосував керівник і побіг cron -fразом з іншим процесом.

Редагувати: Ще одна проблема - мені також не вдалося змусити його працювати під час запуску контейнера з HOST мережею. Дивіться цю проблему також тут: https://github.com/phusion/baseimage-docker/isissue/144



3

Я писав сценарій встановлення оболонки, який створює інший сценарій для очищення старих даних транзакцій з бази даних. У рамках цього завдання довелося налаштувати щоденне cronзавдання для виконання у довільний час, коли завантаження бази даних було низьким.

Я створив файл mycronjobіз розкладом cron, ім'ям користувача та командою та скопіював його у /etc/cron.dкаталог. Мої два gotchas:

  1. mycronjob Файл повинен був належати root, щоб запустити
  2. Мені довелося встановити дозволи на файл 644 - 664 не запустився.

Проблема з дозволом з’явиться /var/log/syslogяк щось подібне до:

Apr 24 18:30:01 ip-11-22-33-44 cron[40980]: (*system*) INSECURE MODE (group/other writable) (/etc/crontab)
Apr 24 18:30:01 ip-11-22-33-44 cron[40980]: (*system*) INSECURE MODE (group/other writable) (/etc/cron.d/user)

Перший рядок стосується /etc/crontabфайлу, а пізніше - файлу, під яким я розмістив /etc/cront.d.


2

Рядок, написаний таким чином, що crontab не розуміє. Це потрібно правильно записати. Ось CrontabHowTo .


1
Як це можна налагодити?
Адам Матан

Перегляд журналу помилок Cron - найпоширеніший спосіб. IIRC 'crontab -e' також аналізує синтаксис після того, як ви відредагували файл - але це може бути не універсальним.
пбр

2

Демон Крона міг би працювати, але насправді не працює. Спробуйте перезапустити cron:

sudo /etc/init.d/cron restart

3
Я НІКОЛИ не бачив цього випадку у виробництві. Це не означає, що цього не сталося - просто те, що я його не бачив протягом 30 років, якими я користувався UNIX та Linux. Крон шалено міцний.
пбр

1
Я не впевнений, але думаю, що це насправді просто трапилося зі мною. Я спробував pidofcron і нічого не отримав. Спробував за допомогою serviceутиліти, і він сказав, що cron вже працює. Просто запустив цю команду і побіг pidofзнову, і я отримаю результат.
Колін

2

Запис на cron через "crontab -e" з аргументом ім'я користувача у рядку. Я бачив приклади користувачів (або sysadmins), які пишуть свої сценарії оболонки і не розуміють, чому вони не автоматизуються. Аргумент "user" існує в / etc / crontab, але не у визначених користувачем файлах. так, наприклад, ваш особистий файл буде приблизно таким:

# m h dom mon dow command

* * */2  *   *  /some/shell/script

тоді як / etc / crontab буде:

# m h dom mon dow user   command

* * */2  *   *  jdoe   /some/shell/script

То чому б ти робив останнє? Ну, залежно від того, як ви хочете встановити свої дозволи, це може стати дуже складним. Я написав сценарії для автоматизації завдань для користувачів, які не розуміють тонкощів або не хочуть зациклюватися на зухах. Встановивши дозволи --x------, я можу зробити сценарій виконуваним, не маючи змоги його прочитати (і, можливо, випадково змінити) його. Однак я, можливо, захочу запустити цю команду з кількома іншими з одного файлу (таким чином полегшуючи обслуговування), але переконайтеся, що вихід файлу призначений правильним власником. Це (принаймні в Ubuntu 10.10) порушує як неможливість прочитати файл, так і виконати, а також вищезгадану проблему із введенням періодів у / etc / crontab (що, як не дивно, не викликає помилок при проходженні через crontab -e) .

Як приклад, я бачив випадки sudo crontab -eвикористовуваного для запуску скрипту з правами root, з відповідним chown username file_outputсценарієм оболонки. Недбало, але це працює. IMHO, Більш витончений варіант - це ввести його /etc/crontabіз задекларованим ім’ям користувача та належними дозволами, тому він file_outputпереходить у потрібне місце та власника.


"Так (принаймні в Ubuntu 10.10) відбувається перерва як на неможливість прочитати файл, так і виконати ....." Я повинен уточнити: / etc / crontab (за замовчуванням) вимагає дозволу для читання та виконання, тоді як ви МОЖЕТЕ запустіть "sudo crontab -e", щоб створити cronjob, який перевизначає як необхідність дозволу "w", так і проблему з розширеннями типу ".sh". Я не встиг розірвати код крона і перевірити, чому це працює, просто деталь, яку я помітив.
Менж

2

Розробляючи те, що Аарон Пірт згадував про багатослівний режим, іноді сценарії, які не перебувають у режимі багатослідової роботи, ініціалізуються, але не завершаться, якщо поведінка включеної команди за замовчуванням включає виведення рядка або більше на екран, коли програма починається. Наприклад, я написав резервний скрипт для нашої інтрамережі, який використовував curl, утиліту, яка завантажує або завантажує файли на віддалені сервери, і є досить зручною, якщо ви можете отримати доступ до вказаних віддалених файлів лише через HTTP. Використання "curl http://something.com/somefile.xls " спричинило зависання сценарію, який я написав, і ніколи не завершений, оскільки він виписує новий рядок, за яким слідує лінія прогресу. Мені довелося скористатися тихим прапором (-ми), щоб сказати йому, щоб не виводити жодної інформації, і написати свій власний код для обробки, якщо файл не вдалося завантажити.


1
Для програм, які не мають безшумного режиму, ви можете перенаправити їх вихід на /dev/null. Наприклад: some-command > /dev/nullЦе буде перенаправляти лише стандартний вихід, а не вихід помилок (що зазвичай те, що ви хочете, оскільки ви хочете, щоб вас повідомляли про помилки). Для перенаправлення помилок виводу також використовуйте some-command &> /dev/null.
Елія Каган

Так, це була моя перша думка, коли я писав вищезгаданий сценарій. Я забуваю, чому я не використовував це, можливо, якусь нестандартну поведінку, яка обійшла вказане рішення. Я знаю, що багатослівний / інтерактивний режим є типовим для деяких команд (я дивлюся на ВАС, scp!), А це означає, що вам потрібно перевести вказаний вихід для безперебійної роботи скриптів оболонки.
Mange

2

Хоча ви можете визначити змінні середовища у своєму crontable, ви не в скрипті оболонки. Тому такі конструкції не працюватимуть:

SOME_DIR=/var/log
MY_LOG_FILE=${SOME_LOG}/some_file.log

BIN_DIR=/usr/local/bin
MY_EXE=${BIN_DIR}/some_executable_file

0 10 * * * ${MY_EXE} some_param >> ${MY_LOG_FILE}

Це тому, що змінні не інтерпретуються в crontable: всі значення приймаються літерально. І це те саме, якщо опустити дужки. Тож ваші команди не працюватимуть, а ваші журналові файли не будуть записуватися ...

Натомість ви повинні визначити всі змінні середовища безпосередньо:

SOME_DIR=/var/log
MY_LOG_FILE=/var/log/some_file.log

BIN_DIR=/usr/local/bin
MY_EXE=/usr/local/bin/some_executable_file

0 10 * * * ${MY_EXE} some_param >> ${MY_LOG_FILE}

2

Коли завдання виконується в межах cron, stdin закривається. Програми, які діють по-різному, залежно від того, доступний чи ні stdin, поводяться по-різному між сеансом оболонки та в cron.

Приклад - програма goaccessдля аналізу файлів журналів веб-сервера. Це НЕ працює в cron:

goaccess -a -f /var/log/nginx/access.log > output.html

і goaccessпоказує сторінку довідки замість створення звіту. У оболонці це можна відтворити

goaccess -a -f /var/log/nginx/access.log > output.html < /dev/null

Виправлення goaccessполягає в тому, щоб змусити його читати журнал зі stdin замість читання з файлу, тож рішення - змінити запис crontab на

cat /var/log/nginx/access.log | goaccess -a > output.html

2

У моєму випадку cron і crontab мали різних власників.

НЕ працює, у мене було таке:

User@Uva ~ $ ps -ef | grep cron | grep -v grep
User    2940    7284 pty1     19:58:41 /usr/bin/crontab
SYSTEM   11292     636 ?        22:14:15 /usr/sbin/cro 

В основному мені довелося запустити cron-config і правильно відповісти на питання. Є момент, коли мені потрібно було ввести пароль користувача Win7 для мого облікового запису "Користувач". З прочитаного, який я робив, схоже, це потенційна проблема безпеки, але я єдиний адміністратор однієї домашньої мережі, тому я вирішив, що це нормально.

Ось послідовність команд, яка мене змусила:

User@Uva ~ $ cron-config
The cron daemon can run as a service or as a job. The latter is not recommended.
Cron is already installed as a service under account LocalSystem.
Do you want to remove or reinstall it? (yes/no) yes
OK. The cron service was removed.

Do you want to install the cron daemon as a service? (yes/no) yes
Enter the value of CYGWIN for the daemon: [ ] ntsec

You must decide under what account the cron daemon will run.
If you are the only user on this machine, the daemon can run as yourself.
   This gives access to all network drives but only allows you as user.
To run multiple users, cron must change user context without knowing
  the passwords. There are three methods to do that, as explained in
  http://cygwin.com/cygwin-ug-net/ntsec.html#ntsec-nopasswd1
If all the cron users have executed "passwd -R" (see man passwd),
  which provides access to network drives, or if you are using the
  cyglsa package, then cron should run under the local system account.
Otherwise you need to have or to create a privileged account.
  This script will help you do so.
Do you want the cron daemon to run as yourself? (yes/no) no

Were the passwords of all cron users saved with "passwd -R", or
are you using the cyglsa package ? (yes/no) no

Finding or creating a privileged user.
The following accounts were found: 'cyg_server' .
This script plans to use account cyg_server.
Do you want to use another privileged account name? (yes/no) yes
Enter the other name: User

Reenter: User


Account User already exists. Checking its privileges.
INFO: User is a valid privileged account.
INFO: The cygwin user name for account User is User.

Please enter the password for user 'User':
Reenter:
Running cron_diagnose ...
... no problem found.

Do you want to start the cron daemon as a service now? (yes/no) yes
OK. The cron daemon is now running.

In case of problem, examine the log file for cron,
/var/log/cron.log, and the Windows event log (using /usr/bin/cronevents)
for information about the problem cron is having.

Examine also any cron.log file in the HOME directory
(or the file specified in MAILTO) and cron related files in /tmp.

If you cannot fix the problem, then report it to cygwin@cygwin.com.
Please run the script /usr/bin/cronbug and ATTACH its output
(the file cronbug.txt) to your e-mail.

WARNING: PATH may be set differently under cron than in interactive shells.
         Names such as "find" and "date" may refer to Windows programs.


User@Uva ~ $ ps -ef | grep cron | grep -v grep
    User    2944   11780 ?        03:31:10 /usr/sbin/cron
    User    2940    7284 pty1     19:58:41 /usr/bin/crontab

User@Uva ~ $

1
Хоча це добре задокументовано, це виглядає як специфічний для Cygwin пункт; чи справді він належить до askubuntu?
sxc731

2

На моїх серверах RHEL7 виконуватимуться завдання root root, але завдання користувачів не будуть. Я виявив, що без домашнього каталогу завдання не будуть працювати (але ви побачите хороші помилки в / var / log / cron). Коли я створив домашній каталог, проблема була вирішена.


2

Якщо ви відредагували файл crontab за допомогою редактора Windows (через samba чи щось подібне), а нові рядки замінено на \ n \ r або просто \ r, cron не запуститься.

Крім того, якщо ви використовуєте /etc/cron.d/* і один із цих файлів має \ r в ньому, cron переміститься через файли та зупиниться, коли він потрапить у невірний файл. Не знаєте, чи це проблема?

Використання:

od -c /etc/cron.d/* | grep \r
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.