В crontab я видел пару ответов, в которых пользователи запрашивали способ запуска каждые 5 минут:
*/5 * * * * command
Или каждые 5 минут со смещением:
10-59/5 * * * * command
Я видел несколько креативных решений, когда люди делали двухстрочные crontab за каждые 90 минут:
0 0-21/3 * * * whatever
30 1-22/3 * * * whatever
Благодаря одному из ответов ниже (спасибо @khaled) вот еще одно творческое решение для 3h30mins:
0 0-23/7 * * * whatever
30 3-23/7 * * * whatever
Есть ли общее решение для каждой проблемы x минут? Например, сейчас мне нужно каждые 3 часа 30 минут.
Чтобы устранить повторяющийся тег: связанный вопрос явно отличается - есть общие советы по настройке и отладке заданий cron. Я имею в виду конкретную проблему, когда мы достигаем пределов синтаксиса cron. Я ищу общий алгоритм для решения проблемы «каждые более 60 минут», которая не рассматривается в связанном вопросе.
Вам просто нужно самостоятельно посчитать, чтобы найти нужные задания, которые подходят для вашего времени.
0 0-23/7 * * * whatever
30 3-23/7 * * * whatever
Из этих двух примеров (при смещении 30 минут) можно сделать простой алгоритм:
duration * 2
.Если вы думаете больше, вы можете придумывать аналогичные решения примерно каждые 75 минут.
Редактировать:
Cron нельзя использовать для всех типов запланированных заданий. Например, выполнение задания один раз в месяц в последний день месяца. Вы не можете просто сделать это с помощью cron, потому что последний день месяца меняется от месяца к другому. Чтобы решить эту проблему, вы можете запустить задание cron в возможном диапазоне значений последнего дня месяца (28-31) и проверить, действительно ли это последний день в сценарии, прежде чем выполнять фактическое задание.
Ставим результат команды
date +%s
в переменной в вашем crontab. Что-то вроде TIME = 1497950105. Теперь в вашем crontab вам нужна запись вроде
* * * * * /bin/bash -c '[[ $(($(date +\%s)-TIME)) -gt seconds ]] && TIME=$(date +\%s) && whatever'
Где секунды - это количество секунд, которое вы хотите (12600 в вашем случае).
Или если вы хотите подождать 3 часа 30 минут после завершения программы
* * * * * /bin/bash -c '[[ $(($(date +\%s)-TIME)) -gt seconds ]] && whatever && TIME=$(date +\%s)'
Редактировать: Я исправил свой предыдущий ответ:
Другое решение (без использования TIME):
* * * * * /bin/bash -c '[[ $((($(date +\%s) / 60) % minutes)) -eq 0 ]] && whatever'
Где минут 210 в вашем случае.
Изменить 2:
Как предлагает MSalters, лучше запускать запись каждые N минут, где N - наибольший общий делитель между 60 и вашим временным интервалом в минутах.
В этом случае я думаю, что вы просто пытаетесь использовать cron, чтобы делать то, что он не может делать сам по себе (конечно, за исключением решений, в которых cron на самом деле периодически выполняет вспомогательный скрипт, и в этом случае я бы сказал, что это не cron Сам решаю проблему).
Решение с интервалом 3 часа 30 минут не совсем правильное. Это было данное решение:
0 0-23/7 * * * whatever
30 3-23/7 * * * whatever
Причина, по которой это неверно, заключается в том, что cron будет запускать задание в периоды 21:00 и 00:00, что составляет интервал в 3 часа, а не 3 часа 30 минут.
Общее решение для всех временных интервалов должно иметь возможность обрабатывать случаи, которые не делятся равномерно на 24 часа. Хотя он не делится равномерно на 24 часа, он равномерно делится на неделю! Самый простой способ думать об этом - делать два перекрывающихся подхода «каждые 7 часов», например:
0 0-23/7 * * 1 whatever
0 4-23/7 * * 2 whatever
0 1-23/7 * * 3 whatever
0 5-23/7 * * 4 whatever
0 2-23/7 * * 5 whatever
0 6-23/7 * * 6 whatever
0 3-23/7 * * 7 whatever
30 3-23/7 * * 1 whatever
30 0-23/7 * * 2 whatever
30 4-23/7 * * 3 whatever
30 1-23/7 * * 4 whatever
30 5-23/7 * * 5 whatever
30 2-23/7 * * 6 whatever
30 6-23/7 * * 7 whatever
Лучшее, что вы можете сделать - это делиться на неделю, потому что месяцы не идеально совпадают с неделями, и это единственный способ сделать это. Например, интервал ровно каждые 12 минут является тривиальным для одной строки crontab, но интервал точно каждые 11 минут невозможен, потому что 10080 не делится на 11. (10080 - это количество минут в неделе).
Определенно можно было бы написать алгоритм для решения тех случаев, когда это возможно, но это явно не стоит особого труда, особенно с учетом того, как на самом деле будут выглядеть решения.