Pull to refresh

Comments 66

ИМХО Было бы полезно так же упомянуть как unset некоторые переменные окружения для выполняемой программы. Ту же MAILTO, например.

Насколько видел из кода, переменные нельзя удалить в самом кроне, только перезаписать типа MAILTO=""

cron был для меня настоящим открытием. Штука, которая просто работает.

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

Многое из того, что сейчас делают на всяких крутых штуках вроде докера, кубернета и так далее командами по 10 человек, раньше за то же самое время делал один на голом линуксе плюс баш плюч крон.
UFO just landed and posted this here
Проще проекты раскидать по виртуалкам, а на них уже настроить нужный часовой пояс.

Для разработчиков нет никакой другой таймзоны, окромя UTC.

UFO just landed and posted this here

Простите, что поздно отвечаю, как-то пропустил.


а переменная CRON_TZ тут не помогает?

UFO just landed and posted this here
Здесь будет ветка переписи тех, кто случайно выполнял «crontab -r», промахнувшись мимо клавиши «e» :)
Из статьи узнал про crontab -r, до этого всегда открывал crontab -e и удалял текст внутри. Судя по ветке, и хорошо, что не пользовал.
бэкап — наше все) Он и спас при промахе.
Лет 15 назад я искал удаленную подработку. До этого я не имел опыта Linux и работал только на FreeBSD.
И вот в первый-же день (скорее даже час) работы я «промахнулся» и узнал, что в Centos у crontab нет «глупых» вопросов а-ля
# crontab -r
remove crontab for root? 

Всю ночь я его восстанавливал по логам. Странно, что не уволили…
Зато ты теперь очень осторожен и ценен!
Я вот случайно под рутом точку забыл и написал
rm -rf /*
а надо было
 rm -rf ./*
Вот это было веселье на всю ночь! В итоге всё окей, много чего узнал полезного)

Ограничение, что крон может запускать задачи не чаще чем раз в секунду заставляло писать свои костыли.
Крайне не хватало возможности указать частоту опроса, пускай и с перезапуском самого крона.

Да, интересный вопрос. Ограничение по-умолчанию — минута, является большим для машины и относительно маленьким для человека. Предлагают скриптиком чаще запускать.
Больше похоже на компромис, который сложился исторически, когда машины были ещё не так быстры. Частота в секунду для современных компьютеров была бы приемлемой, наверно.

Смею предположить, что, во-первых, ежесекундные задачи — дело редкое, а во-вторых, в свое время ежесекундный запуск чего-либо было непозволительной роскошью.

Ежесекундные задачи может и редкость, но вот разнести запуск ежеминутных в пределах минуты или запускать задачи два, три, четыре раза в минуту бывает нужно. То есть посекундная точность не помешала бы.

это решаемая проблема. Какой-нибудь файл-лок можно, например, хватать на запуске задач.


Хотя я понимаю, о чем вы. Но мы вот делали именно flock -x в похожей ситуации.

Это просто, bash скрипт запускающий нужное количество команд через слип прекрасно работал у нас лет 10
Если есть задача запускать что-то раз в секунду, то проще и правильнее демон написать.
всё равно не хватает иногда такой штуки */20 для секунд. в остальном крон это прелесть.
… ну и упомянуть Cron для Windows тоже стоило бы ;), на порядок удобнее встроенного планировщика.
nnCron на сайте разработчика
Заходим к разработчику

Для себя использовал версию nnCron Lite — хватает заглаза.
Пользователи уже описывали использование полной версии, не знаю, насколько это описание актуально
Описание на русском
Гуру cron-a! Подскажите по следующей ситуации — потребовалось мне как-то хранить логи почтовых треэйсов N-месяцев с граничного Антиспам-сервера. Задача проста до нельзя — раз в сутки-двое копировать файл /var/log/mail.log, аппендить к нему дату и ложить в какую-то папочку. Код crontab-a был приблизительно такой: 0 2 * * * cp /var/log/mail/ /home/user/mail_`%d%m%Y. Так вот в этом случае крон не отрабатывал, логи честно не помню, т.к. скорее всего не ыбло ничего вразумительного в них. Поступил проще — создал скрипт /home/user/copy_log.sh, вставил в него cp /var/log/mail/ /home/user/mail_`%d%m%Y, добавил «o+х» (каюсь, можно было и u+x, то бишь запуск только root-у) на скрипт, а сам скрипт закинул в crontab: 0 2 * * * /home/user/copy_log.sh. Вот тогда всё заработало без косяков. Вопрос — почему крон не работал напрямую с командой cp и требует скриптовую прослойку?
Скорее всего проблема в переменных среды, которые при запуске от cron совсем не те что при запуске из консоли. Например не то содержание переменной path и программы/команды просто не находит. Можно попробовать прописать везде абсолютные пути, можно вывести переменные в файлы и посмотреть какие там значения. Не претендую на правильность советов :)

Надо бы указать версию вашего дистрибутива и крона. Но вообще использование скриптов-оберток — стандартный подход.


Логов, кстати, у кронов может и не быть, стандартно бывает только отправка на почту, указанную в переменной MAILTO.


Если хочется разобраться подробней, то можно попровать вызывать прямиком шелл с вашей командой, так, как его вызывает сам cron: /bin/sh -c "cp /from/file /to/file". Часто путаница бывает связана с тем, что шелл по умолчанию берется POSIX-совместимый и запущенный в неинтерактивном режиме.

Лог можно настроить, но есть ли смысл в нём? Обычно им выполняют скрипты, которые логируют в своём окружении, елси это пёрл, питон или пхп.
Однажды ковырялся в консоли и тут появляется сообщение: у вас есть новый емейл, по такому пути можете найти. «Ничего себе, консоль мне пишет про емейлы» — подумал я и, действительно, нашёл сообщение от крона в емейлах. Очень удобно оказалось.

да, в старые добрые MAILTO хорошо работало. Но сейчас несколько потеряло актуальность.

Скорее всего в этом и дело. Спасибо, что подсказали. Хорошо что хоть из POSIX-режима можно скриптом вызывать шельные команды. Без этого ценность крона была бы околонулевой. Кстати в виндовом шедулере я встречал аналогичный трабл — длинные команды с кучей аргументов, напрямую прописанные в задании не работают. Как только закидываешь всё задание в батник — вуаля! Всё работает. Имхуется мне, что POSIX и там пробежал.
Не требует. Пишут, что нужно \% или через переменную среды делать. Ссылка
Скрипт удобен тем, что его можно как вручную для теста запустить, так и кроном выполнить.
И в случае crontab -r скрипт останется.

точно, надо ж экранировать проценты, т.к. проценты в кроне означают перенос строки, для передачи в команды нескольких строк :-)


Из стандарта:


A <percent-sign> character in this field shall be translated to a <newline>. Any character preceded by a
<backslash> (including the '%' ) shall cause that character to be treated literally. Only the first line (up to a
'%' or end-of-line) of the command field shall be executed by the command interpreter. The other lines shall > be made available to the command as standard input.

вам ниже ответили, что проценты надо экранировать :-) Там же я привел выжимку из стандарта

У logrotate'а есть параметр olddir и описание задачи выглядит так, как будто стоило использовать его для копирования, а сам logrotate запускать cron'ом

Если каждые сутки, то можно вообще ограничиться средствами logrotate с параметром daily
Для винды есть nnCron и nnCron Lite (последний — бесплатен).
Формат crontab такой же + дополнения.
Я использую версию 1.17.119.0 от 2005 года, которая, как заявлено, работает на Win95 — WinXP, но у меня работает и на Win7 и кажется даже на Win10.

Неоднократно пробовал пользоваться родным виндовым планировщиком, но потом опять уходил на nnCron Lite.
Ну как есть… Скорее был. В 2005 я его тоже использовал, но он не поддерживается с 2008. И помнится, под Win 7 он уже требовал каких-то телодвижений для нормальной работы.
Так-то крутая была софтина, но она написана на форте и скрипты под нее надо было писать на диалекте форта, а это чудовищно. Обратная польская запись хороша для машин, а не для людей.

Для тех, кто ещё не столкнулся с этой замечательной фичей, процитирую википедию:


Все условия (времени запуска) проверяются по «логическому И», кроме условий «день недели» и «день месяца» — указанные совместно, они обрабатываются по «логическому ИЛИ», то есть «по любому из дней», что отражено в документации (Ubuntu, Debian, FreeBSD). Однако такая логика неочевидна и не позволяет создать условие типа «первый понедельник каждого месяца» или «каждую пятницу в 13 число».

Приходится писать костыли в баше.

Так можно же непосредственно в кронтабе. Например, настроить правило на 13 число, а в коде команды проставить if [ $(date +%u) = 5 ].

Или [ "$(date '+\%w')" = "1" ] && cmd.
Так и делаю. Но это всё же синтаксис баша, а не самого кронтаба.

Т.е. Cron ежеминутно проверяет таблицы и выполняет команды при совпадении с системным временем/датой. Конечно возможно это что-то необычное, но если необходимо запустить задачу в определенную секунду, миллисекунду?

Секунды (тем более — миллисекунды) традиционно не делали, т.к. для всех пользователей каждую секунду проверять задачи — дело неблагодарное. Тут Крон не поможет.


Еще более гранулярно, на миллисекундах, фактически не имеет смысла делать, т.к. вся эта возня с шеллами, форками и экзеками уже занимает сотни миллисекунд, точности не выйдет.


В таких случаях вам понадобится что-то очень специальное.

Главная фишка систем, созданных на базе крона, это высокая надежность, достигнутая малой кровью. Т.е. например вы можете сделать скрипт, который падает каждый второй раз, запускать его из крона и все будет работать, лишь бы скрипт не портил данные.
Тогда для себя я решил, насчет секунд, что раз cron имеет точность в минуту, значит так и надо и этот гвоздь торчит из стула не просто так. Поэтому ИМХО, если нужна точность лучше, чем минуты, нужно делать это в своей программе, а из крона только проверять, не упала ли эта программа и перезапускать в случае падения.
А еще проще использовать тот же supervisord или systemctl, которые:
1) включаются вместе с ОС и имеют возможность запуска скрипта после запуска зависимостей (т.е., когда включилась база данных или обработчик очередей)
2) функция контроля (перезагружать ли после ошибки или штатного завершения работы, сколько попыток сделать, с каким диапазоном сделать перезапуск)
3) все это логгируется и вытаскивается через тот же journalctl
А сам скрипт исполняет работу и спит от 5 до 30 секунд. Чтобы не текла память, можно также завершать скрипт после получаса-часа работы, тогда systemctl автоматически включит задачу повторно.
Поэтому cron в этом смысле выглядит довольно странным и не универсальным решением.
> Поэтому cron в этом смысле выглядит довольно странным и не универсальным решением.
«Каждая программа в своем развитии доходит до необходимости отправлять электронную почту» © Не помню кто.
В смысле каждая программа тащит в себя все фичи, до которых только может дотянуться.
Крон не странная программа, это очень простая штука, для 95% задач его хватает и в этом его сила. В простоте.
Универсальные решения это не UNIX way.
Для многих задач — да, я его активно использую для автозапуска многих задач.
Но для наблюдателя над ходом исполнения программы — возможно, это не самое эффективное решение, хотя и довольно простое. Конечно, все зависит от программы, которая запускается кроном, но supervisord или systemctl в этом плане более заточенные.
ИМХО у них разное назначение.
cron — запуск скриптов, которые выполняют задачу и выходят.
supervisord, systemctl — запуск демонов.
> но если необходимо запустить задачу в определенную секунду, миллисекунду?
Если нужно запустить программу в нужную миллисекунду, то тут уже нехило пахнет специальной операционной системой реального времени да еще и с очерь хорошей синхронизацией времени.
Шаги и интервалы можно смешивать:

# Запускается каждую вторую минуту первых десяти минут каждого часа
0-10/2 * * * * /path/to/exec

Я бы не использовал в описании интервально-шаговых событий слово «каждую». Отнюдь, не придираюсь, просто зачастую формулировку «каждую вторую» воспринимают как «каждую чётную».
С учётом данного примера с 0-й левой границей интервала это справедливо, но может вызывать непонимание конструкций вида
1-11/2 * * * * /path/to/exec

Разумеется и здесь можно говорить «каждую вторую начиная с 1», но сам стараюсь использовать формулировки «через две минуты», «с шагом в две минуты».

согласен, сам раньше путал. Поправлю.

Что раздражает у crontab, так это отсутствие (?) подтверждения при удалении через crontab -r. Особенно с учётом того, что клавиши "e" и "r" расположены рядом на клавиатуре, поэтому набирая "crontab -e" нужно быть КРАЙНЕ внимательным.

UFO just landed and posted this here

Да судя по коду cronie не очень радикально изменился :-) цо… викси жив!

Коллега. А где же anacron? Где команды at?

Это отдельные программы с отдельной историей :-) Хотя в redhat вроде как anacron вместе с cron поставляется...

Это все программы планирования заданий/выполнение заданий по времени.

Думаю, не лишним было бы пояснение про пользователей указываемых в /etc/crontab в шестом столбце. У меня cronie ругается на него и говорит, что нет такой команды. Про это почему-то нигде нет информации.

Sign up to leave a comment.