Почему не работают скрипты crontab?


525

Часто crontabсценарии не выполняются по расписанию или как ожидалось. Для этого есть множество причин:

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

Вики-сообщество призвано объединить основные причины, по которым crontabскрипты выполняются не так, как ожидалось. Запишите каждую причину в отдельном ответе.

Пожалуйста, включите одну причину для ответа - подробности о том, почему он не выполнен - ​​и исправьте (и) по этой одной причине.

Пожалуйста, пишите только специфичные для cron проблемы, например команды, которые выполняются как ожидается от оболочки, но ошибочно выполняются cron.


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

Я думаю, что лучший способ отладки cron - это проверить системный журнал и найти проблемы.
Сунил Кумар

В моем случае - электронная почта отправлялась в мою папку СПАМ, так что ..... проверьте это, прежде чем тратить часы на отладку: D
almaruf

Отключения электричества
Йозеф Климук

Ответы:


501

Другая среда

Cron передает минимальный набор переменных среды для ваших заданий. Чтобы увидеть разницу, добавьте фиктивную работу вот так:

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

Дождитесь /tmp/env.outputсоздания, затем снова удалите задание. Теперь сравните содержимое /tmp/env.outputс выходом envзапуска в обычном терминале.

Общей «ошибкой» здесь является то, что PATHпеременная окружения отличается. Может быть , ваш хрон сценарий использует команду somecommandнайденную в /opt/someApp/bin, который вы добавили PATHв /etc/environment? cron игнорирует PATHэтот файл, поэтому запуск somecommandиз вашего скрипта завершится неудачно при запуске с cron, но будет работать при запуске в терминале. Стоит отметить, что переменные from /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 Если такие каталоги доступны для записи другим, система уже взломана.
Гейра

6
@pbr Системный администратор может невольно удалить корневую файловую систему. Вы не можете защититься от сисадминов, делающих глупые ошибки. Если вы установите более новую версию интерпретатора, который не имеет обратной совместимости, я бы ожидал поломку независимо от этого. Разумный способ справиться с этим - установить его как другую команду. Например, у вас есть Python версии 2.x и установить Python 3, вы устанавливаете его как Python3, а не Python. А что касается / opt / someApp / bin, с какой стати у него не было бы вменяемых прав / владения? любой вменяемый администратор обеспечит вменяемые права / владение системными файлами.
Гейра

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
это такой демонстратор, почему он не был исправлен за столько лет cron?
Capi Etheriel

2
Кажется, исправлено в Vixie cron: man crontabв Ubuntu 10.10 говорится: «cron требует, чтобы каждая запись в crontab заканчивалась символом новой строки. Если в последней записи в crontab отсутствует символ новой строки, cron будет считать crontab (по крайней мере, частично) неработающим. и отказаться от его установки. " (И дата в конце 19 апреля 2010 года.)
Мариус Гедминас

19
@barraponto На самом деле это ошибка в новых текстовых редакторах. Символ «новой строки» должен быть символом завершения строки , поэтому последняя строка в текстовом файле должна заканчиваться символом новой строки, который не отображается в редакторе. Vi и vim правильно используют этот символ, а cron был создан до того, как новые редакторы начали свое странное поведение ... Следовательно, воспроизводим его, сохраняя и включая пустую строку.
Изката

6
Если вы редактируете crontab, используя crontab -eего, проверьте синтаксис файла перед разрешением сохранения, включая проверку на новую строку.
Том Харрисон-младший

2
@ Chan-HoSuh, согласно man-странице "cron требует, чтобы каждая запись в crontab заканчивалась символом новой строки. Если в последней записи в crontab отсутствует символ новой строки, cron будет считать crontab (по крайней мере, частично) сломанным и откажется установить его. " Это поведение будет вызываться при редактировании, а затем при сохранении файла crontab с использованием этой -eопции, и не зависит от редактора.
Том Харрисон-младший

139

Cron демон не работает. Я действительно облажался с этим несколько месяцев назад.

Тип:

pgrep cron 

Если вы не видите номера, значит, cron не запущен. sudo /etc/init.d/cron startможет быть использован для запуска cron.

РЕДАКТИРОВАТЬ: Вместо того, чтобы вызывать сценарии инициализации через /etc/init.d, используйте служебную утилиту, например

sudo service cron start

РЕДАКТИРОВАТЬ: Также вы можете использовать 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
Коллин

1
service crond startесли его сентос / RHEL
Срихари Карант

91

Сценарий для имен файлов в cron.d/, cron.daily/, cron.hourly/и т.д., не должно содержать точку ( .), в противном случае выполняется-части будет пропускать их.

Смотрите run-parts (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.
2012 г.

@pbr: имеет смысл. По крайней мере, это было бы полезно для отладки, если run-parts --test(или другой мнимый вариант, например --debug, выводил бы файлы, которые он пропускает, включая причину.
Рабарберски

9
Если это функция, то она не очень хорошая :( Многие люди используют точку в имени файла (наиболее часто встречается backup.sh). Если вы хотите, чтобы скрипт прекратил выполнение, наиболее логичным способом будет удалите его из каталога "cron.d"
MatuDuke

8
Это настолько плохая особенность, что это фактически ошибка. Обычной практикой является требование определенного окончания (например, «.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
    

предложение bash очень полезно, исправлена ​​проблема с моим cron.
Максим Галушка

Это просто вызвало у меня 1 час возни / проблем. Еще более озадачивает, если вы не знаете, в чем проблема, - сценарий будет запускаться вручную просто отлично, если вы используете обычную оболочку bash, но не с cron. Спасибо!
Hendy

Давным-давно я столкнулся с чем-то связанным: команда sourceв bash, но не sh. В cron / sh используйте точку: . envfileвместо source envfile.
кунгфу

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

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

40

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

sudo service cron restart

6
Да, после изменения часового пояса в системе необходимо либо перезапустить все службы, которые заботятся о том, который час, или перезагрузить компьютер. Я предпочитаю перезагрузку, чтобы убедиться, что я все поймал.
2012 г.

О боже, убитые часы на этом. Пробовал перезапуск службы после * * * * * 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
см. ответ гейры, вы можете (должны) определить
путь Крона

9
Bzzt. Вам НЕ нужно определять ПУТЬ - лучше использовать абсолютные пути. «потому что исполняемый файл может быть где-то еще на каком-то другом компьютере» не превосходит «я хочу, чтобы он запускал именно эту программу, а не какой-то другой, который кто-то вставил в путь перед моей исходной программой»
pbr

1
да, это было для меня, за пределами cron я мог выполнить команду напрямую, внутри cron требовался полный /usr/bin/whateverпуть
Anentropic

32

Если в вашей команде crontab есть %символ, cron пытается его интерпретировать. Поэтому, если вы использовали какую-либо команду, содержащую %в себе (например, спецификацию формата для команды date), вам нужно будет ее избежать.

Это и другие полезные ошибки здесь:
http://www.pantz.org/software/cron/croninfo.html


Это то, что привело к сбою моей работы в Cron за последнюю неделю. В конце концов выяснилось, что у моего свидания не было escape-символа (обратная косая черта для любых других людей, ищущих, что такое escape-символ). Ура!
Валиен


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 

Источник: Включить ведение журнала crontab в Debian Linux

В некоторых системах (Ubuntu) отдельный файл регистрации для cron не включен по умолчанию, но связанные с cron журналы появляются в файле syslog. Можно использовать

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

для просмотра сообщений, связанных с cron.


У меня есть Debian (wheezy), но нет /etc/init.d/rsyslog, только inetutils-syslogd и sysklogd. Нужно ли что-то устанавливать или просто перезапустить один из двух?
hgoebl

18

Если ваш cronjob вызывает GUI-приложения, вы должны сообщить им, какой DISPLAY они должны использовать.

Пример: запуск Firefox с помощью cron.

Ваш скрипт должен содержать export DISPLAY=:0где-то.


aplay нуждался в этом по некоторым причинам. спасибо
ИльяБек

* * * * * 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

Сценарий зависит от местоположения. Это связано с тем, что в скрипте всегда используются абсолютные пути, но это не совсем одно и то же. Ваша задача cron может потребоваться перейти cdв определенный каталог перед запуском, например, задача rake в приложении Rails может быть в корне приложения для Rake, чтобы найти правильную задачу, не говоря уже о соответствующей конфигурации базы данных и т. Д.

Итак, запись в crontab

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 = production

Или, чтобы сделать запись в crontab более простой и менее хрупкой:

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

со следующим кодом в /home/<user>/scripts/session-purge.sh:

cd / var / www / production / current
/ usr / bin / rake db: session_purge RAILS_ENV = production

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 вызывает команду с параметром --verbose

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

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

Сценарий выполнялся нормально при выполнении из оболочки, но не работал при запуске из crontab, поскольку подробный вывод выводится на стандартный вывод при запуске из оболочки, но нигде при запуске из crontab. Легко исправить, чтобы удалить «V»:

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

5
Почему это вызывает сбой? Проблемы с буфером?
Адам Матан,

Любые выходные данные или ошибки, передаваемые с помощью заданий cron, будут отправлены на ваш почтовый ящик. Поэтому мы никогда не должны забывать заботиться об этих ошибках / выходных данных. Мы можем перенаправить их в любой файл или / dev / null
Nischay

10

Самая частая причина, по которой я видел сбой cron в неверно указанном расписании. Требуется практика, чтобы указать работу, запланированную на 23:15, 15 23 * * *вместо * * 11 15 *или 11 15 * * *. День недели для рабочих мест после полуночи также запутывается, MF - 2-6после полуночи, нет 1-5. Конкретные даты, как правило, являются проблемой, поскольку мы редко используем их * * 3 1 *не 3 марта. Если вы не уверены, проверьте расписание cron онлайн на https://crontab.guru/ .

Если вы работаете с разными платформами, используя неподдерживаемые параметры, такие как 2/3временные спецификации, это также может привести к сбоям. Это очень полезная опция, но она не всегда доступна. Я также сталкивался с проблемами со списками как 1-5или 1,3,5.

Использование неквалифицированных путей также вызвало проблемы. Путь по умолчанию обычно /bin:/usr/binтаков, что будут выполняться только стандартные команды. Эти каталоги обычно не имеют желаемой команды. Это также влияет на сценарии, использующие нестандартные команды. Другие переменные среды также могут отсутствовать.

Полное уничтожение существующего crontab вызвало у меня проблемы. Я сейчас загружаю из файла копию. Это может быть восстановлено из существующего crontab, используя, crontab -lесли он забит. Я храню копию crontab в ~ / bin. Это комментируется повсюду и заканчивается строкой # EOF. Это загружается ежедневно из записи в crontab, например:

#! / USR / бен / кронтаб
# Перезагрузить этот crontab
#
54 12 * * * $ {HOME} / bin / crontab

Приведенная выше команда reload опирается на исполняемый файл crontab с путём взрыва, на котором выполняется crontab. В некоторых системах требуется запуск crontab в команде и указание файла. Если каталог является сетевым, то я часто использую crontab.$(hostname)в качестве имени файла. Это в конечном счете исправит случаи, когда неправильный crontab загружен на неправильный сервер.

Использование файла обеспечивает резервное копирование того, каким должен быть crontab, и позволяет crontab -eавтоматически откатывать временные изменения (единственное время, которое я использую ). Доступны заголовки, которые помогают правильно настроить параметры планирования. Я добавил их, когда неопытные пользователи будут редактировать crontab.

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


3
Это охватывает три отдельные проблемы. Могут ли они быть разделены на отдельные ответы?
Элия ​​Каган

9
Можете ли вы объяснить, как 30 23 * * * переводится на 23:15?
Джелтон

@JYelton Это было явно неправильно, так и должно быть 15 23 * * *. Исправлено сейчас.
Мелебиус

7

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

Если система использует PAM и учетная запись заблокирована, это может остановить запуск cronjob. (Я проверял это на 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 <ИМЯ ПОЛЬЗОВАТЕЛЯ>

как root, чтобы разблокировать учетную запись, и crontab должен снова работать.


7

Если у вас есть такая команда:

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

и это не работает, и вы не можете видеть какой-либо вывод, это не обязательно означает, что cron не работает. Сценарий может быть поврежден, и вывод будет передан в stderr, который не будет передан в / tmp / output. Проверьте, что это не так, записав этот вывод:

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

чтобы увидеть, поможет ли это вам решить вашу проблему.


3

=== Предупреждение Docker ===

Если вы используете докер,

Я считаю правильным добавить, что мне не удалось заставить cron работать в фоновом режиме.

Чтобы запустить задание cron внутри контейнера, я использовал supervisor и запустил cron -fвместе с другим процессом.

Изменить: Еще одна проблема - мне также не удалось заставить его работать при запуске контейнера с сетью HOST. Смотрите эту проблему здесь также: https://github.com/phusion/baseimage-docker/issues/144



3

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

Я создал файл mycronjobс расписанием cron, именем пользователя и командой и скопировал его в /etc/cron.dкаталог. Мои две ошибки:

  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' выполняет синтаксический анализ после того, как вы также отредактировали файл - но это может быть не универсальным.
2012 г.

2

Cron-демон может быть запущен, но на самом деле не работает. Попробуйте перезапустить cron:

sudo /etc/init.d/cron restart

3
Я никогда не видел этот случай в производстве. Это не значит, что этого не произошло - просто я не видел этого 30 лет, когда использовал UNIX и Linux. Крон безумно крепок.
2012 г.

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

2

Запись в cron через "crontab -e" с аргументом username в строке. Я видел примеры пользователей (или системных администраторов), пишущих свои сценарии оболочки и не понимающих, почему они не автоматизируют. Аргумент «пользователь» существует в / 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в скрипте оболочки. Небрежно, но это работает. ИМХО, более изящный вариант - поставить его /etc/crontabс объявленным именем пользователя и надлежащими разрешениями, поэтому file_outputотправляется в нужное место и владельцу.


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

2

Основываясь на том, что Аарон Пирт упомянул о подробном режиме, иногда сценарии, не находящиеся в подробном режиме, будут инициализироваться, но не завершаться, если поведение включенной команды по умолчанию будет выводить строку или более на экран после запуска процедуры. Например, я написал сценарий резервного копирования для нашей интрасети, который использовал curl, утилиту, которая загружает или загружает файлы на удаленные серверы, и это очень удобно, если вы можете получить доступ к указанным удаленным файлам только через HTTP. Использование 'curl http://something.com/somefile.xls ' приводило к зависанию написанного мной скрипта, который никогда не завершался, поскольку он выплевывал новую строку, за которой следовала строка прогресса. Мне пришлось использовать флаг без вывода сообщений (-s), чтобы запретить выводить какую-либо информацию, и написать собственный код для обработки, если файл не удалось загрузить.


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 cron, а задания пользователей - нет. Я обнаружил, что без домашнего каталога задания не будут выполняться (но вы увидите хорошие ошибки в / 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.