Могу ли я выполнять работу cron чаще, чем каждую минуту?


44

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


4
Каково ваше намерение? Является ли cron правильным инструментом для этого?
Мануэль Фо

Хороший вопрос.
Прит Сангха

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

Ответы:


36

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


18
Часть «вы также рискуете некоторыми серьезными проблемами, если работа выполняется дольше, чем интервал между запусками». неверно, и в этом случае оно будет в равной степени применяться к заданиям, которые выполняются каждые 5 минут, каждый час или каждый месяц. Эта проблема имеет решения (использование pid-файла или чего-либо еще и проверка того, выполняется ли уже задание перед его выполнением). Таким образом, проблема в том, что cron просто не допустит эту частоту, но неверно говорить, что что-то не так в выполнении задачи каждую минуту.
Маттео

2
Я имел в виду, если вы не используете pidfile. Если ваша работа выполняется каждые X минут и занимает больше X минут, вы в конечном итоге будете складывать задания. Если ваша работа также ограничена каким-либо ресурсом (процессор, пропускная способность сети / диска и т. Д.), То выполнение большего количества за один раз может занять еще больше времени, и в конечном итоге ваш компьютер превратится в беспорядочный беспорядок.
сумерки

2
Вы можете использовать, run-oneчтобы программа / даже скрипт PHP не запускали дублирующийся экземпляр. sudo apt-get install run-oneи назовите этоrun-one <normal command>
kouton

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

@Mantriur Потому что автор вопроса нашел его полезным и пометил его как принятый ответ? :) А если серьезно, то вы уже определили проблему самостоятельно: многие другие современные ответы предлагали хакерские решения, которые было бы неразумно использовать в производственной системе. (Также имейте в виду, что некоторые из других ответов появились только спустя годы после того, как вопрос был задан, поэтому они еще не были готовы принять!)
duskwuff

37

Кандидат на самое творческое злоупотребление командой 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 против системных таймеров .

Я постараюсь опубликовать пример в ближайшее время.


6
Я даю +1 за чистую щеку
Мэтт Симмонс

2
Было бы неплохо иметь немного больше объяснений с этим ответом. Команда nohup является новой для меня. Интернет говорит мне, что нужно игнорировать сигнал зависания. Что все еще оставляет меня в замешательстве.
Donquixote

2
@donquixote: Важно признать, что команда в целом в моем ответе не рекомендуется, поэтому следует использовать слово «неправильное использование». Однако, чтобы прояснить для вас кое-что, поскольку есть полезные методы, я попытаюсь описать несколько. &Заставляет команду работать в фоновом режиме, возвращая управление в командную строку немедленно. Использование nohupкоманды приводит к тому, что фоновый процесс (в данном случае watch) игнорирует сигнал зависания, который отправляется при выходе из оболочки, например при закрытии терминала. ...
Приостановлено до дальнейшего уведомления.

1
... Перенаправление вывода с использованием >/dev/nullприводит к тому, что вывод отбрасывается и предотвращает создание nohup.outфайла, который в противном случае был бы создан, если стандартный вывод является терминалом.
Приостановлено до дальнейшего уведомления.

1
@donquixote: Не только через 30 секунд, каждые 30 секунд. Остальное, чтобы он работал в фоновом режиме без присмотра, чтобы быть более похожим на cron. Если вы хотите использовать sleep, вам нужно написать цикл, чтобы процесс повторялся (повторяет watchли это для вас, как делает cron). Тебе все равно нужно nohupи &. Дополнительной проблемой sleepбудет смещение времени. --preciseВариант watchпозволяет избежать этого. Без него или при использовании sleepв цикле временной интервал содержит время, необходимое для запуска команд или сценария, добавляемое к нему, поэтому каждый запуск становится позже и позже ...
Приостановлено до дальнейшего уведомления.

13

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


10
* * * * * /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 лучшее решение, подходящее для вашей среды.


было задано:without a sleep command
Филипп

10
Другим посетителям, которые находят этот вопрос, все равно, будет ли использоваться команда sleep :)
donquixote

8

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

Опция, которая хорошо сработала для меня - это часто встречающийся

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


1
Frequent-cron хорошо сработал и для нас, и работает на многих наших производственных системах. У нас никогда не было проблем с этим.
Homer6

2

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

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

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

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


1

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

Запись 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команду

2
Может кто-нибудь объяснить это новичку в Linux - с за и против? Спасибо ..
а20

@asvany Я думаю, что мне нравится это решение, но как a20, не могли бы вы опубликовать некоторые объяснения для Linux "зеленый", пожалуйста? ти.
JoelAZ

0

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

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

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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.