Могу ли я выполнять работу cron чаще, чем каждую минуту?
Можно ли запускать задание cron каждые 30 секунд без команды sleep?
10 ответов
Если ваша задача должна выполняться так часто, cron - неправильный инструмент. Помимо того, что он просто не будет запускать задания так часто, вы также рискуете столкнуться с серьезными проблемами, если задание выполняется дольше, чем интервал между запусками. Перепишите свою задачу так, чтобы она демонизировалась и выполнялась постоянно, а затем, при необходимости, запустите ее из cron (при этом убедитесь, что она не перезапустится, если она уже запущена).
Кандидат на самое творческое злоупотребление командой 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
,&
-watch
Команда запускается в фоновом режиме, а управление возвращается в терминал или родительский процесс.
Обратите внимание, что nohup
, перенаправление вывода и &
оператор фонового управления не является специфичным для watch
,
Вот объяснение примера yourprog
сценарий:
date
- Выводит текущую дату и / или время. Это может также установить их.+%M.%S.%N
- Это определяет формат вывода дляdate
использовать.%M
текущая минута,%S
текущая секунда и%N
текущая наносекунда.>> yourprog.out
- Это перенаправляет выводdate
команда в файл с именемyourprog.out
, Двойное значение больше, чем приводит к тому, что вывод добавляется в файл при каждом вызове, а не перезаписывается предыдущее содержимое.
Редактировать:
Возможно, еще одна вещь, которой можно злоупотреблять (или, возможно, это законное использование), это системные таймеры.
Смотрите systemd/Timers как замену 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;
Одна простая стратегия для ОС Linux — создать службу SystemD, например/etc/systemd/system/myservice.service
:
[Install]
WantedBy=multi-user.target
[Unit]
Description=Bmon
StartLimitIntervalSec=30
StartLimitBurst=2
[Service]
ExecStart=/usr/bin/bash /home/janie/myservice.sh
Restart=always
Затем вmyservice.sh
:
#!/usr/bin/bash
while true
do
/home/janie/run_every_10_sec
sleep 10
done
Это завершит запуск команды/home/janie/run_every_10_sec
каждые 10 секунд.
Включитьmyservice.service
, бегатьsudo systemctl enable myservice
.
Решение, если это для вашего собственного сценария или если вы можете обернуть его:
- Получить и запомнить время начала.
- Если файл блокировки, к которому вы будете обращаться позже, присутствует, и сценарий не работает в течение 60 секунд, подождите секунду и проверьте снова. (например, во время / сна)*
- Если файл блокировки все еще присутствует по истечении 60 секунд, выйдите с предупреждением об устаревшей блокировке.
- Сенсорный файл блокировки.
- Пока скрипт не работал в течение 60 секунд, зациклите текущую задачу с желаемой продолжительностью сна.
- Удалить файл блокировки.
- Добавьте как мелко крона.
- Боб твой дядя.
Меньше головной боли, чем создание и мониторинг демона.
* Если вы используете PHP, помните clearstatcache().