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

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

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

<p>кандидат на <em> самое креативное</em> <strong> неправильное использование </strong> команды linux:</p><pre><code>nohup watch -n 30 --precise yourprog >/dev/null & </code></pre><p>если <code>yourprog</code> состоит из:</p><pre><code>date +%m.%s.%n >> yourprog.out </code></pre><p>тогда <code>yourprog.out</code> может выглядеть так:</p><pre><code>50.51.857291267 51.21.840818353 51.51.840910204 52.21.840513307 52.51.842455224 53.21.841195858 53.51.841407587 54.21.840629676 </code></pre><p>показывая довольно хороший уровень точности.</p><p>вот объяснение частей команды:</p><ul> <li><code>nohup</code> - это удерживает команду, которая следует за ней, в данном случае <code>watch</code>, от выхода из терминала.</li> <li> <a href="http://manpages.ubuntu.com/manpages/artful/man1/watch.1.html"><code>watch</code></a> - эта программа запускает команду несколько раз. обычно первый экран вывода команды отображается каждый раз, когда <code>watch</code> запускает команду.</li> <li><code>-n 30</code> - интервал запуска команды. в этом случае это каждые тридцать секунд.</li> <li><code>--precise</code> - без этой опции <code>watch</code> запускает команду <strong> через </strong> <em> интервал</em> секунд. при этом каждый запуск команды <em> начинается</em> <strong> на </strong> интервал, если это возможно. если эта опция не была указана в примере, время будет позже и позже более чем на 30 секунд каждый раз из-за времени, необходимого для запуска и выполнения команды (<code>yourprog</code>).</li> <li><code>yourprog</code> - программа или командная строка для выполнения <code>watch</code>. если командная строка содержит специальные символы для командной консоли (например, пробел или точка с запятой), ее необходимо заключить в кавычки.</li> <li><code>>/dev/null</code> - "больше" перенаправляет вывод команды, выполняемой <code>watch</code>, в файл, <code>/dev/null</code>. этот файл отбрасывает любые данные, записанные в него. это предотвращает запись вывода на экран или, поскольку <code>nohup</code> используется, предотвращает отправку вывода в файл с именем <code>nohup.out</code>.</li> <li><code>&</code> - команда <code>watch</code> выполняется в фоновом режиме, и управление возвращается в терминал или родительский процесс.</li> </ul><p>обратите внимание, что <code>nohup</code>, перенаправление вывода и <code>&</code> оператор управления фоном не относится к <code>watch</code>.</p><p>вот объяснение примера сценария <code>yourprog</code>:</p><ul> <li><code>date</code> - выводит текущую дату и/или время. это может также установить их.</li> <li><code>+%m.%s.%n</code> - указывает формат вывода для использования <code>date</code>. <code>%m</code> текущая минута, <code>%s</code> текущая секунда и <code>%n</code> текущая наносекунда.</li> <li><code>>> yourprog.out</code> - перенаправляет вывод команды <code>date</code> в файл с именем <code>yourprog.out</code>. двойное значение "больше" приводит к тому, что вывод добавляется в файл при каждом вызове, а не перезаписывается предыдущее содержимое.</li> </ul><p><strong> редактировать </strong>:</p><p>возможно, еще одна вещь, которой можно злоупотреблять (или, возможно, это законное использование), это системные таймеры.</p><p>смотрите <a href="https://wiki.archlinux.org/index.php/systemd/timers#as\_a\_cron\_replacement">systemd/timers как замена cron</a> и <a href="https://unix.stackexchange.com/questions/278564/cron-vs-systemd-timers">cron против systemd таймеров</a> .</p><p>я постараюсь опубликовать пример в ближайшее время.</p>

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

<pre><code>* * * * * /path/to/program * * * * * sleep 30; /path/to/program </code></pre><p>не забудьте записать что-нибудь в свою программу, чтобы она завершалась, если предыдущий экземпляр уже запущен.</p><pre><code>#!/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 </code></pre><p>конечно, это все еще оставляет очень маленькую возможность для сбоя, поэтому поищите в google лучшее решение, подходящее для вашей среды.</p>

<p>вы можете сделать это с помощью стороннего программного обеспечения.</p><p>опция, которая хорошо сработала для меня: <a href="https://github.com/homer6/frequent-cron">часто-cron</a> </p><p>это позволяет с точностью до миллисекунды и дает вам возможность отложить следующее выполнение до завершения текущего.</p>

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

<h3>мое самое простое и любимое решение для этой задачи:</h3><p>запись cron:<br> <code>* * * * * flock -w0 /path/to/script /path/to/script</code></p><p>сценарий:<br> <code>while true;do echo doing something; sleep 10s;done</code></p><h3>ленивая альтернатива :)</h3><pre><code>* * * * * flock -w0 /path/to/log watch -n 10 echo doing >> /path/to/log </code></pre><p>или</p><pre><code>* * * * * flock -w0 /path/to/log watch -n 10 /path/to/script </code></pre><h3>профи</h3><ul> <li>использование команды <code>flock</code> позволяет избежать запуска сценария несколькими экземплярами одновременно. это может быть очень важно в большинстве случаев.</li> <li>команды <code>flock</code> и <code>watch</code> доступны в большинстве установок linux</li> </ul><h3>минусы</h3><ul> <li>остановка такого рода "службы" требует двух шагов <ul> <li>закомментируйте запись cron</li> <li>убить скрипт или команду <code>watch</code></li> </ul> </li> </ul>

<p>решение, если это для вашего собственного сценария или если вы можете обернуть его:</p><ol> <li>получить и запомнить время начала.</li> <li>если файл блокировки, к которому вы будете обращаться позже, присутствует и сценарий не выполняется в течение 60 секунд, подождите секунду и проверьте снова. (например, во время/сна) *</li> <li>если файл блокировки все еще присутствует по истечении 60 секунд, выйдите с предупреждением об устаревшей блокировке.</li> <li>сенсорный файл блокировки.</li> <li>пока сценарий не работает в течение 60 секунд, зациклите текущую задачу с желаемой продолжительностью сна.</li> <li>удалить файл блокировки.</li> <li>добавьте как мелко крона.</li> <li>боб твой дядя.</li> </ol><p>меньше головной боли, чем создание и мониторинг демона.</p><p>* если вы используете php, помните clearstatcache ().</p>