Итак, у меня есть хрон, который мне нужно запускать каждые 30 секунд.
Вот что у меня есть:
*/30 * * * * /bin/bash -l -c 'cd /srv/last_song/releases/20120308133159 && script/rails runner -e production '\''Song.insert_latest'\'''
Он работает, но работает ли он каждые 30 минут или 30 секунд?
Кроме того, я читал, что cron, возможно, не лучший инструмент для использования, если я запускаю его так часто. Есть ли другой лучший инструмент, который я могу использовать или установить в Ubuntu 11.04, который будет лучшим вариантом? Есть ли способ исправить вышеуказанный cron?
ubuntu
cron
scheduled-tasks
Мэтт Элхотиби
источник
источник
Ответы:
У вас есть
*/30
в спецификаторе минут - это означает каждую минуту, но с шагом 30 (другими словами, каждые полчаса). Такcron
как не доходит до субминутных разрешений, вам нужно будет найти другой путь.Одна из возможностей, хотя и немного сложная (а) , состоит в том, чтобы иметь два задания, одно из которых смещено на 30 секунд:
Вы увидите, что я добавил комментарии и отформатировал их, чтобы их было легко синхронизировать.
Обе
cron
работы фактически выполняются каждую минуту, но последняя будет ждать полминуты, прежде чем выполнять «мясо» задания/path/to/executable
.Для других (не
cron
основанных) вариантов смотрите другие ответы здесь, особенно те, которые упоминаютfcron
иsystemd
. Это, вероятно, предпочтительнее, если ваша система может их использовать (например, установкаfcron
или наличие дистрибутиваsystemd
).Если вы не хотите использовать решение kludgy, вы можете использовать решение на основе цикла с небольшой модификацией. Вам все равно придется управлять тем, чтобы ваш процесс работал в какой-то форме, но после сортировки должен работать следующий скрипт:
Хитрость заключается в том, чтобы использовать его,
sleep 30
но запускать его в фоновом режиме до запуска полезной нагрузки. Затем, после того, как полезная нагрузка закончена, просто подождите, покаsleep
закончится фон .Если полезная нагрузка занимает
n
секунды (гдеn <= 30
), ожидание после полезной нагрузки будет30 - n
секундами. Если это займет более 30 секунд, то следующий цикл будет отложен до завершения полезной нагрузки, но не дольше.Вы увидите, что у меня есть отладочный код, который начинается на минутной границе, чтобы на выходе было легче следовать. Я также постепенно увеличиваю максимальное время полезной нагрузки, так что вы в конечном итоге увидите, что полезная нагрузка превышает 30-секундное время цикла (выводится дополнительная пустая строка, поэтому эффект очевиден).
Далее следует примерный цикл (где циклы обычно начинаются через 30 секунд после предыдущего цикла):
Если вы хотите избежать грязного решения, это, вероятно, лучше. Вам все еще понадобится
cron
задание (или его эквивалент), чтобы периодически обнаруживать, работает ли этот сценарий, и, если нет, запускать его. Но сам скрипт обрабатывает время.(а) Некоторые мои коллеги сказали бы, что моя специальность - это кладжи :-)
источник
Ты не можешь Cron имеет 60-секундную зернистость.
источник
&&
вместо( ; )
.&&
оператор короткого замыкания, так что следующая команда в цепи не выполняется , если предыдущий не удалось.Степень детализации Cron составляет несколько минут и не предназначена для того, чтобы просыпаться каждую
x
секунду, чтобы что-то запустить. Запустите повторяющуюся задачу в цикле, и она должна делать то, что вам нужно:источник
while [ true ]
заставит ли вас иметь много экземпляров одного и того же скрипта, так как cron будет запускать новый каждую минуту?sleep $remainingTime
оставшееся время составляло 30 минус время, затраченное на задание (и ограничить его нулем, если это заняло> 30 секунд). Таким образом, вы берете время до и после фактической работы и вычисляете разницу.Если вы используете новейшую ОС Linux с SystemD, вы можете использовать модуль таймера SystemD для запуска вашего скрипта на любом уровне детализации, который вы пожелаете (теоретически до наносекунд), и - если вы хотите - гораздо более гибкие правила запуска, чем когда-либо позволял Cron , Не
sleep
требуется кладжиДля настройки требуется немного больше, чем для отдельной строки в файле cron, но если вам нужно что-то лучше, чем «Каждую минуту», оно того стоит.
Модель таймера SystemD в основном такова: таймеры - это единицы, которые запускают сервисные единицы по истечении таймера .
Таким образом, для каждого сценария / команды, которую вы хотите запланировать, у вас должен быть блок обслуживания, а затем дополнительный блок таймера. Один таймер может включать в себя несколько расписаний, поэтому обычно вам не требуется более одного таймера и одного сервиса.
Вот простой пример, который регистрирует «Hello World» каждые 10 секунд:
/etc/systemd/system/helloworld.service
:/etc/systemd/system/helloworld.timer
:После настройки этих устройств (
/etc/systemd/system
как описано выше, для общесистемной настройки или~/.config/systemd/user
для пользовательской настройки) необходимо включить таймер (но не службу), выполнивsystemctl enable --now helloworld.timer
(--now
флаг также запускает таймер немедленно, в противном случае он будет запущен только после следующей загрузки или входа пользователя).Здесь
[Timer]
используются следующие поля раздела:OnBootSec
- запускать службу через много секунд после каждой загрузки.OnUnitActiveSec
- запустить службу через много секунд после последнего запуска службы. Это то, что заставляет таймер повторяться и вести себя как задание cron.AccuracySec
- устанавливает точность таймера. Таймеры имеют такую же точность, как это поле, и по умолчанию используется 1 минута (имитирует cron). Основная причина не требовать наилучшей точности - повысить энергопотребление - если SystemD может запланировать следующий запуск так, чтобы он совпадал с другими событиями, он должен реже разбудить ЦП. В1ms
приведенном выше примере не является идеальным - я обычно устанавливаю точность1
(1 секунду) в моих суб-минутных запланированных работ, но это означало бы , что если вы посмотрите на журнал , показывающий «Hello World» сообщения, вы бы увидели , что это часто поздно на 1 секунду. Если вы согласны с этим, я предлагаю установить точность до 1 секунды или более.Как вы, возможно, заметили, этот таймер не очень хорошо имитирует Крона - в том смысле, что команда не запускается в начале каждого периода настенных часов (т.е. она не запускается на 10-й секунде на часах, потом 20 и тд). Вместо этого это просто происходит, когда таймер истекает. Если система загрузилась в 12:05:37, то в следующий раз команда будет запущена в 12:05:47, затем в 12:05:57 и т. Д. Если вас интересует фактическая точность настенных часов, вы можете хотите заменить
OnBootSec
иOnUnitActiveSec
поля , и вместо того, чтобы установитьOnCalendar
правила с графиком , который вы хотите (который, насколько я понимаю , не может быть быстрее , чем на 1 секунду, используя формат календаря). Приведенный выше пример также можно записать так:Последнее замечание: как вы, наверное, догадались,
helloworld.timer
устройство запускаетhelloworld.service
устройство, потому что у него одинаковое имя (за исключением суффикса типа устройства). Это значение по умолчанию, но вы можете изменить это, установивUnit
поле для[Timer]
раздела.Больше подробностей можно найти по адресу:
man systemd.timer
man systemd.time
man systemd.service
man system.exec
источник
Нет необходимости в двух записях cron, вы можете поместить их в одну:
так в вашем случае:
* * * * * /bin/bash -l -c "cd /srv/last_song/releases/20120308133159 && script/rails runner -e production '\''Song.insert_latest'\'' ; sleep 30 ; cd /srv/last_song/releases/20120308133159 && script/rails runner -e production '\''Song.insert_latest'\''"
источник
Вы можете проверить мой ответ на этот похожий вопрос
По сути, я включил туда bash-скрипт с именем «runEvery.sh», который вы можете запускать с помощью cron каждую 1 минуту и передавать в качестве аргументов реальную команду, которую вы хотите запустить, и частоту в секундах, с которой вы хотите ее запускать.
что-то вроде этого
* * * * * ~/bin/runEvery.sh 5 myScript.sh
источник
Используйте часы:
источник
$ watch --interval .10 php some_file.php
? илиwatch
работает только с .sh файлами?--interval .30
не будет выполняться дважды в минуту. Т.е.watch -n 2 "sleep 1 && date +%s"
он будет увеличиваться каждые 3 с.watch
был разработан для использования терминалом, поэтому - хотя он может работать без терминала (запустить сnohup
последующим выходом из системы) или с поддельным терминалом (таким какscreen
) - он не имеет возможностей для поведения, подобного cron, такого как восстановление после сбоя, перезапуск после загрузки и т. д.Задание Cron нельзя использовать для планирования задания с интервалом в несколько секунд. то есть вы не можете запланировать выполнение задания cron каждые 5 секунд. Альтернативой является написание сценария оболочки, в котором используется
sleep 5
команда.Создайте скрипт оболочки каждые 5-seconds.sh, используя цикл bash while, как показано ниже.
Теперь выполните этот сценарий оболочки в фоновом режиме,
nohup
как показано ниже. Это продолжит выполнение сценария даже после выхода из сеанса. Это будет запускать скрипт оболочки backup.sh каждые 5 секунд.источник
backup.sh
запуск занимает 1,5 секунды, он будет выполняться каждые 6,5 секунд. Есть способы избежать этого, напримерsleep $((5 - $(date +%s) % 5))
Используйте fcron ( http://fcron.free.fr/ ) - дает вам детализацию в считанные секунды и делает ее лучше и более многофункциональной, чем cron (vixie-cron) и стабильной. Раньше я делал глупости, например, когда на одной машине работало около 60 php-скриптов в очень дурацких настройках, и это все еще выполняло свою работу!
источник
в рубрике
/etc/cron.d/
новый создать файл
excute_per_30s
будет запускать cron каждые 30 секунд
источник
В настоящее время я использую метод ниже. Работает без проблем.
Если вы хотите запускать каждые N секунд, то X будет 60 / N, а Y будет N .
Спасибо.
источник
YOUR_COMMANDS
наYOUR_COMMANDS &
так, чтобы команда запускалась в фоновом режиме, в противном случае, если команда занимает больше доли секунды - она задержит следующий запуск. Так, при X = 2 и Y = 30, если команда занимает 10 секунд - она запускается через минуту, а затем через 40 секунд вместо 30. Kudus to @paxdiablo./bin/bash -c
часть (включая кавычки аргументов), скрипт запускается только каждую минуту, игнорируя итерацию (в моем случаеX=12
иY=5
).Задание Crontab можно использовать для планирования задания в минутах / часах / днях, но не в секундах. Альтернатива:
Создайте скрипт для выполнения каждые 30 секунд:
Используйте
crontab -e
и crontab для выполнения этого скрипта:источник
Вы можете запустить этот скрипт как сервис, перезапускать каждые 30 секунд
Зарегистрировать услугу
Вставьте в команду ниже
Сервисы перезагрузки
Включить услугу
Запустить сервис
Проверьте статус вашего сервиса
источник
Спасибо за все хорошие ответы. Для простоты мне понравилось смешанное решение с управлением crontab и разделением времени в скрипте. Вот что я сделал, чтобы запускать скрипт каждые 20 секунд (три раза в минуту). Линия Crontab:
Автор сценария:
источник
написать один сценарий оболочки создать файл .sh
нано каждые30 секунд
и написать сценарий
затем установите cron для этого скрипта crontab -e
(* * * * * /home/username/every30second.sh)
этот файл cron вызывает файл .sh каждые 1 минуту и в команде .sh файл запускается 2 раза за 1 минуту
если вы хотите запустить скрипт в течение 5 секунд, замените 30 на 5 и измените цикл следующим образом:
For (( i=1; i <= 12; i++ ))
когда вы выбираете для любой секунды, затем рассчитать 60 / свою секунду и написать в цикле For
источник
У меня просто была похожая задача и я использовал следующий подход:
Мне нужно было периодически убивать -3 (чтобы отслеживать стек программы) каждые 30 секунд в течение нескольких часов.
Это здесь, чтобы быть уверенным, что я не потеряю выполнение watch, если потеряю оболочку (проблема с сетью, сбой Windows и т. Д.
источник
Посмотрите на часто-cron - он старый, но очень стабильный, и вы можете перейти на микросекунды. На данный момент, единственное, что я хотел бы сказать против этого, - это то, что я все еще пытаюсь понять, как установить его вне init.d, но в качестве нативной службы systemd, но, конечно, до Ubuntu 18 он работает просто нормально все еще используя init.d (расстояние может отличаться в последних версиях). У него есть дополнительное преимущество (?), Заключающееся в том, что он не будет порождать другой экземпляр сценария PHP, если не завершен предыдущий, что уменьшает потенциальные проблемы утечки памяти.
источник
Запустите в цикле оболочки, например:
источник
60
должно быть30
, вы можете двигаться , чтоwget
внутри вif
заявлении, в противном случае он выполняется каждую секунду. В любом случае, я не уверен, насколько это лучше, чем просто синглsleep 30
. Если бы вы отслеживали фактическое время UNIX, а не счетчик, это имело бы значение.