Чи можу я виконувати роботу з хроном частіше, ніж кожну хвилину?


44

Чи можна запускати роботу cron кожні 30 секунд без команди сну?


4
Який ваш намір? Чи є правильним інструментом для використання cron?
Мануель Фокс

Гарне питання.
Преет Сангга

Наприклад, в даний час я використовую cron, щоб змінити фонове зображення мого робочого столу, щоб обійти обмеження нативної перемикача фонових зображень (не занурюючись у підкаталоги). Якби я хотів перемикатися частіше, ніж раз на хвилину, я би зіткнувся з цим обмеженням крона. (хоча у рідного перемикача bg є таке ж обмеження)
donquixote

Відповіді:


36

Якщо ваше завдання потрібно виконувати так часто, cron - це неправильний інструмент. Крім того, що він просто не запускає завдання так часто, ви також ризикуєте отримати серйозні проблеми, якщо робота займе більше часу, ніж інтервал між запусками. Перепишіть своє завдання, щоб демонструвати та запускати послідовно, після чого запускайте його з крону (якщо переконайтеся, що воно не буде повторно запущено, якщо воно вже працює).


18
Частина "Ви також ризикуєте отримати серйозні проблеми, якщо робота триватиме більше часу, ніж інтервал між запусками". це неправда, і якби це було, воно застосовуватиметься однаково до завдань, які виконуються кожні 5 хвилин, кожну годину або кожен місяць з цього питання. У цій проблемі є рішення (використання pidfile чи будь-чого іншого та перевірка, чи робота вже запущена перед її запуском). Таким чином, проблема полягає в тому, що 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 / Таймери в якості заміни хрон і Cron проти Systemd таймерів .

Я спробую опублікувати приклад найближчим часом.


6
Я даю +1 для чистої щоки
Метт Сіммонс,

2
Було б добре трохи пояснити цю відповідь. Команда nohup для мене нова. Інтернет говорить мені, що слід ігнорувати сигнал зависання. Що все ще залишає мене розгубленим.
donquixote

2
@donquixote: Важливо визнати, що команда в цілому в моїй відповіді не рекомендується робити, отже, вживання слова "неправильне використання". Однак, щоб трохи уточнити для вас речі, оскільки є корисні методи, я спробую описати декілька. &Змушує команду працювати у фоновому режимі, повертаючи управління в командний рядок негайно. Використання nohupкоманди змушує фоновий процес (в даному випадку watch) ігнорувати сигнал зависання, який надсилається при виході оболонки, наприклад, коли ви закриваєте термінал. ...
Денніс Вільямсон

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

1
@donquixote: відтепер не лише 30 секунд, кожні 30 секунд. Решта полягає в тому, щоб він працював без нагляду у фоновому режимі, щоб бути схожішим на крони. Якщо ви хочете використовувати 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
Іншим відвідувачам, які знаходять це питання, все одно, чи використовується команда сну :)
donquixote

8

Це можна зробити за допомогою програмного забезпечення сторонніх виробників.

Варіант, який добре працює для мене, - частота-cron

Це дозволяє отримати мілісекундну точність і дає можливість відкласти наступне виконання до тих пір, поки не закінчиться поточне.


1
Frequent-cron добре працював і для нас, і використовує багато наших виробничих систем. У нас ніколи не було проблеми з цим.
Homer6

2

У мене виникнуть кілька проблем:

(1) іноді система стає зайнятою і не може починати справи точно на 30 секунді, цілком можливо, що в той же час, коли ви виконуєте одну роботу, з’явиться інша робота, і тоді у вас є 2 (або більше) завдання, які роблять те саме річ. Залежно від сценарію, тут може бути якесь суттєве втручання. Таким чином, кодування в такому сценарії повинно містити деякий код, щоб гарантувати, що одночасно працює лише один екземпляр даного сценарію.

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

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


1

моє найпростіше і найулюбленіше рішення цього завдання:

запис у крон:
* * * * * 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

мінуси

  • зупинка такого виду "Сервісу" потребує двох кроків
    • прокоментуйте запис крона
    • вбити сценарій або watchкоманду

2
Чи може хтось, будь ласка, пояснити це новачку Linux - із плюсами та мінусами? Дякую ..
a20

@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.