Назад | Перейти на главную страницу

Могу ли я запускать задание cron чаще, чем каждую минуту?

Можно ли запускать задание cron каждые 30 секунд без команды сна?

Кандидат в самый креативный злоупотребление команды Linux:

nohup watch -n 30 --precise yourprog >/dev/null &

Если yourprog состоит из:

date +%M.%S.%N >> yourprog.out

затем yourprog.out может выглядеть так:

50.51.857291267
51.21.840818353
51.51.840910204
52.21.840513307
52.51.842455224
53.21.841195858
53.51.841407587
54.21.840629676

что указывает на довольно хороший уровень точности.

Вот объяснение частей команды:

  • nohup - Это сохраняет команду, которая следует за ней, watch в этом случае от выхода при выходе из терминала.
  • watch - Эта программа запускает команду повторно. Обычно каждый раз отображается первый экран вывода команды. watch запускает команду.
  • -n 30 - Интервал, с которым запускается команда. В данном случае каждые тридцать секунд.
  • --precise - Без этой опции watch запускает команду после интервал секунд. С его помощью каждый запуск команды начинается на интервал, если возможно. Если бы этот параметр не был указан в примере, время каждый раз увеличивалось бы более чем на 30 секунд из-за времени, необходимого для запуска и выполнения команды (yourprog).
  • yourprog - Программа или командная строка для watch выполнить. Если командная строка содержит символы, специальные для оболочки (например, пробел или точку с запятой), ее необходимо заключить в кавычки.
  • >/dev/null - Больше чем перенаправляет вывод команды, выполняемой watch в файл, /dev/null. Этот файл отбрасывает все записанные в него данные. Это предотвращает вывод вывода на экран или, поскольку nohup используется, это предотвращает отправку вывода в файл с именем nohup.out.
  • & - The watch Команда запускается в фоновом режиме, а управление возвращается терминалу или родительскому процессу.

Обратите внимание, что nohup, перенаправление вывода и & Оператор фонового управления не относится к watch.

Вот объяснение примера yourprog сценарий:

  • date - Выводит текущую дату и / или время. Он также может их установить.
  • +%M.%S.%N - Определяет выходной формат для date использовать. %M текущая минута, %S текущая секунда и %N это текущая наносекунда.
  • >> yourprog.out - Это перенаправляет вывод date команду в файл с именем yourprog.out. Двойное значение больше, чем приводит к тому, что вывод добавляется к файлу при каждом вызове, а не перезаписывается предыдущее содержимое.

редактировать:

Возможно, еще одна вещь, которой можно злоупотребить (или, возможно, это законное использование), - это таймеры systemd.

Видеть systemd / Timers как замена cron и Cron против таймеров systemd.

Постараюсь скоро выложить пример.

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

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

* * * * * /path/to/program
* * * * * sleep 30; /path/to/program

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

#!/bin/sh

if ln -s "pid=$$" /var/pid/myscript.pid; then
  trap "rm /var/pid/myscript.pid" 0 1 2 3 15
else
  echo "Already running, or stale lockfile." >&2
  exit 1
fi

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

Вы можете сделать это с помощью стороннего программного обеспечения.

Для меня хорошо сработал вариант частый cron

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

мое самое простое и любимое решение этой задачи:

запись cron:
* * * * * flock -w0 /path/to/script /path/to/script

сценарий:
while true;do echo doing something; sleep 10s;done

ленивая альтернатива: :)

* * * * * flock -w0 /path/to/log watch -n 10 echo doing >> /path/to/log

или

* * * * * flock -w0 /path/to/log watch -n 10 /path/to/script

профи

  • использование flock команда избегает одновременного запуска сценария несколькими экземплярами. В большинстве случаев это может быть очень важно.
  • flock и watch команды доступны в большинстве установок Linux

минусы

  • остановка такого рода «Услуги» требует двух шагов
    • закомментировать запись cron
    • убить сценарий или watch команда

У меня есть пара проблем:

(1) иногда система загружается и не может начать что-либо точно в 30-секундную точку, тогда возможно, что в то же время, когда вы выполняете одно задание, может появиться другое задание, а затем у вас есть 2 (или более) задания, выполняющих то же самое вещь. В зависимости от сценария здесь могут быть значительные помехи. Таким образом, кодирование в таком сценарии должно содержать некоторый код, гарантирующий, что только один экземпляр данного сценария выполняется одновременно.

(2) Сценарий может иметь много накладных расходов и потреблять больше системных ресурсов, чем вы могли бы пожелать. Это верно, если вы конкурируете с множеством других системных действий.

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

Не точный ответ на ваш вопрос, но я думаю, что некоторым он может быть полезен. Если вы хотите запустить команду каждую секунду, ты мог бы сделать это вот так. Каждую минуту он проходит через 60 секунд, запускает сценарий во вспомогательной оболочке и засыпает на 1 секунду. Вам необходимо убедиться, что вы создали файл блокировки (или аналогичный механизм) и прервали script.pl соответственно (если вы не хотите запускать его несколько раз параллельно).

* * * * * for((i=0; i<60; i++)); do /usr/bin/perl script.pl & sleep 1; done;

Решение, если это для вашего собственного скрипта или если вы можете его обернуть:

  1. Получите и запомните время начала.
  2. Если файл блокировки, к которому вы будете обращаться позже, присутствует и скрипт не запускался в течение 60 секунд, подождите секунду и проверьте снова. (например, while / sleep) *
  3. Если файл блокировки все еще присутствует по прошествии 60 секунд, выйдите с предупреждением об устаревшей блокировке.
  4. Сенсорный файл блокировки.
  5. Пока скрипт не запускался в течение 60 секунд, зациклируйте вашу фактическую задачу с желаемой продолжительностью сна.
  6. Удалить файл блокировки.
  7. Добавить как Minly cron.
  8. Боб твой дядя.

Меньше головной боли, чем создание и мониторинг демона.

* Если вы используете PHP, помните clearstatcache ().