Как поручить крону выполнять задание каждую вторую неделю?

Как поручить крону выполнять задание каждую вторую неделю?

08.12.2008 07:18:40 Просмотров 28 Источник

Я хотел бы запустить работу через cron, которая будет выполняться каждый второй вторник в данное время дня. Ведь каждый вторник-это легко.:

0 6 * * Tue

Но как сделать это "каждый второй вторник" (или, если хотите, - каждую вторую неделю)? Я не хотел бы реализовывать какую-либо логику в скрипте IT self, но сохраняю определение только в cron.

У вопроса есть решение - Посмотреть?

Ответы - Как поручить крону выполнять задание каждую вторую неделю? / How to instruct cron to execute a job every second week?

Является ответом!
xahtep

08.12.2008 07:25:55

Как насчет этого, он сохраняет его в crontab, даже если он точно не определен в первых пяти полях:

0 6 * * Tue expr `date +\%W` \% 2 > /dev/null || /scripts/fortnightly.sh
https://stackoverflow.com/questions/350047/how-to-instruct-cron-to-execute-a-job-every-second-week/350061#comment21347047_350061
Я предполагаю, что это решение имеет проблему в последнюю неделю года. Иногда последняя пятница года приходится на 51-ю неделю, а иногда на 52-ю. Так что это может заставить вас запускать сценарий две недели подряд или один раз в три недели
macetw

05.02.2013 01:47:11

А как насчет каждой 3-й недели?

Вот мое предложение:

0 6 * * Tue expr `date +\%W` \% 3 == 0 > /dev/null || /scripts/fortnightly.sh

... или...

0 6 * * Tue expr `date +\%W` \% 3 == 1 > /dev/null || /scripts/fortnightly.sh

... или, конечно ...

0 6 * * Tue expr `date +\%W` \% 3 == 2 > /dev/null || /scripts/fortnightly.sh

... в зависимости от недельной ротации.

jimmyb

22.02.2013 03:11:56

Cron предоставляет синтаксис' every other ' "/2". Просто следуйте соответствующему полю единицы измерения времени с "/2", и он выполнит cronjob "every other time". В вашем случае...

0 6 * * Tue/2

Вышесказанное следует выполнять каждый второй вторник.

https://stackoverflow.com/questions/350047/how-to-instruct-cron-to-execute-a-job-every-second-week/15022838#comment26043234_15022838
Я проверил эту команду, и она работает каждый вторник, четверг и субботу, а не каждый второй вторник.
https://stackoverflow.com/questions/350047/how-to-instruct-cron-to-execute-a-job-every-second-week/15022838#comment28477546_15022838
Вы случайно не проверяли 0 6 * * Вт/14 ?
https://stackoverflow.com/questions/350047/how-to-instruct-cron-to-execute-a-job-every-second-week/15022838#comment40516978_15022838
жаль-Tue/2 не работает на моей системе :(
Izi

06.05.2013 12:47:32

Синтаксис "/2 " не совпадает с будним днем. Так что мой добавленный к умному выше-это просто использовать 1,15 в день месяца.

0 6 1,15 * * /scripts/fornightly.sh > / dev / null 2> > &1

https://stackoverflow.com/questions/350047/how-to-instruct-cron-to-execute-a-job-every-second-week/16395092#comment45047969_16395092
Обратите внимание, что это происходит 1-го и 15-го числа каждого месяца, а не раз в две недели. Иногда бывает больше 4 недель в месяц. То, что вы имеете здесь, - это "дважды в месяц", а не "через неделю".
https://stackoverflow.com/questions/350047/how-to-instruct-cron-to-execute-a-job-every-second-week/16395092#comment60516964_16395092
Хмм. Я все еще не могу найти решение для аналогичного запроса: задание, которое будет выполняться в полдень каждый альтернативный понедельник в течение года, независимо от месяца. 0 12 * * 1/2 говорит "плохой день недели".
Hans

09.10.2013 07:50:45

Может быть, немного туповато, но можно также создать двух закадычных друзей, по одному на каждый первый вторник и по одному на каждый третий.

Первый расписанию:

0 0 8 ? 1/1 TUE#1 *

Второй расписанию:

0 0 8 ? 1/1 TUE#3 *

Не уверенный в синтаксисе здесь, я использовал http://www.cronmaker.com/ чтобы сделать это.

https://stackoverflow.com/questions/350047/how-to-instruct-cron-to-execute-a-job-every-second-week/19276777#comment52189022_19276777
Планирование задания на первый и третий вторник каждого месяца будет пропускать пятый вторник месяца (например, 31 марта 2015 года), и, конечно, добавление этого пятого вторника будет выполнять задание слишком часто. Отдельно этот ответ ссылается на cron-подобный кварцевый планировщик , а не на традиционный *NIX cron.
https://stackoverflow.com/questions/350047/how-to-instruct-cron-to-execute-a-job-every-second-week/19276777#comment52587027_19276777
Что означает это"#"?
https://stackoverflow.com/questions/350047/how-to-instruct-cron-to-execute-a-job-every-second-week/19276777#comment62813996_19276777
@Asif "позволяет указать такие конструкции, как" вторая пятница " данного месяца."en.wikipedia.org/wiki/Cron
https://stackoverflow.com/questions/350047/how-to-instruct-cron-to-execute-a-job-every-second-week/19276777#comment91496923_19276777
@bigtex777: и какой cron на каком дистрибутиве Linux это реализует? Это определенно не POSIX.
pilcrow

09.10.2013 09:21:37

Ответ

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

Зная, что есть 604800 секунд в неделю (игнорируя изменения DST и високосные секунды, спасибо), и используя GNU date:

0 6 * * Tue expr `date +\%s` / 604800 \% 2 >/dev/null || /scripts/fortnightly.sh

В сторону

Календарная арифметика разочаровывает.

ответ @xahtep потрясающий, но, как отметил в комментариях @Doppelganger, он потерпит неудачу на определенных границах года. Ни один из спецификаторов "неделя года" утилиты date не может помочь здесь. Какой-нибудь вторник в начале января неизбежно повторит недельный паритет последнего вторника в предыдущем году: 2016-01-05 (%V), 2018-01-02 (%U) и 2019-01-01 (%W).

https://stackoverflow.com/questions/350047/how-to-instruct-cron-to-execute-a-job-every-second-week/19278657#comment69667443_19278657
Этот ответ или альтернативная версия этого, использующая секунды в день (а не неделю), например 86400, также имеет ограничение в некоторых крайних случаях: корректировка времени UTC по сравнению с вашим локальным сервером. Предположим, у меня есть работа cron, которая будет работать каждый второй вторник в 3 утра и 11 вечера. Вы можете оказаться в сценарии, который в соответствии с временем UTC (секунды с момента начала эпохи), что они рассматриваются как разные дни. В моем случае 21600 - это мое локальное смещение (сек) относительно эпохи: expr \( `date +%s` - 21600 \) / 86400 % 2и, для тестирования expr \( `date +%s -d "Thursday"` - 21600 \) / 86400 % 2
https://stackoverflow.com/questions/350047/how-to-instruct-cron-to-execute-a-job-every-second-week/19278657#comment69711643_19278657
Смотрите мой ответ ниже для более полного решения.
isaac

26.11.2013 11:59:16

Почему бы не что-то вроде

0 0 1-7,15-21,29-31 * 5

Это уместно?

https://stackoverflow.com/questions/350047/how-to-instruct-cron-to-execute-a-job-every-second-week/20226758#comment30163967_20226758
Это будет продолжаться только первую, третью и пятую неделю каждого месяца.
https://stackoverflow.com/questions/350047/how-to-instruct-cron-to-execute-a-job-every-second-week/20226758#comment31724552_20226758
Но если изменить на 0 0 15-21 * 5 это, по-видимому, делает трюк.
https://stackoverflow.com/questions/350047/how-to-instruct-cron-to-execute-a-job-every-second-week/20226758#comment45047871_20226758
Перечитайте справочную страницу для crontab(5). Ваш формат будет работать каждый день в течение первой недели, каждый день на третьей неделе и каждый день последней недели, а также в любой день, который окажется пятницей. Это очень много пробежек.
notorious.dds

20.10.2015 07:22:08

абзаца ответ велик. Однако это приводит к тому, что fortnightly.sh скрипт работает каждую четную неделю (начиная с эпохи). Если вам нужно, чтобы скрипт работал по нечетным неделям, вы можете немного подправить его ответ:

0 6 * * Tue expr \( `date +\%s` / 604800 + 1 \) \% 2 > /dev/null || /scripts/fortnightly.sh

Изменение 1 на 0 переместит его обратно в четные недели.

alexdourado

23.11.2016 03:43:26

Если вы хотите каждый вторник второй недели только:

00 06 * * 2#2

https://stackoverflow.com/questions/350047/how-to-instruct-cron-to-execute-a-job-every-second-week/40764920#comment91496980_40764920
Какой cron, на котором Linux поддерживает это? Стандартный cron в Linux использует #в качестве разделителя комментариев.
dxdc

21.12.2016 08:19:13

Я обнаружил некоторые дополнительные ограничения вышеприведенных подходов, которые могут потерпеть неудачу в некоторых крайних случаях. Например, рассмотрим:

@xahtep и @Doppelganger обсудили вопросы, используя %Wна определенных границах года выше.

ответ @ pilcrow в какой-то степени обходит это, однако он тоже потерпит неудачу на определенных границах. Ответы в этой и других смежных темах используют количество секунд в сутках (по сравнению с неделей), которые также терпят неудачу на определенных границах по тем же причинам.

Это связано с тем, что эти подходы основаны на времени UTC (дата +%s). Рассмотрим случай, когда мы выполняем работу в час ночи и 10 вечера каждый 2-й вторник.

Предположим, GMT-2:

  • 1 час ночи по местному времени = 11 вечера по UTC вчера
  • 10 вечера по местному времени = 8 вечера UTC сегодня

Если мы проверяем только один раз в день, это не будет проблемой, но если мы проверяем несколько раз-или если мы близки к времени UTC и происходит переход на летнее время, сценарий не будет считать, что это один и тот же день.

Чтобы обойти это, нам нужно вычислить смещение от UTC на основе нашего местного часового пояса, а не UTC. Я не смог найти простой способ сделать это в BASH, поэтому я разработал решение, которое использует быстрый один лайнер в Perl для вычисления смещения от UTC в секундах.

Этот сценарий использует преимущество date +%z, который выводит локальный часовой пояс.

Bash-скрипт :

TZ_OFFSET=$( date +%z | perl -ne '$_ =~ /([+-])(\d{2})(\d{2})/; print eval($1."60**2") * ($2 + $3/60);' )
DAY_PARITY=$(( ( `date +%s` + ${TZ_OFFSET} ) / 86400 % 2 ))

затем, чтобы определить, является ли день четным или нечетным:

if [ ${DAY_PARITY} -eq 1 ]; then
...
else
...
fi
Paul Lemmons

15.11.2018 10:20:10

Если вы хотите сделать это на основе заданной даты начала:

0 6 * * 1 expr \( `date +\%s` / 86400 - `date --date='2018-03-19' +\%s` / 86400 \) \% 14 == 0 > /dev/null && /scripts/fortnightly.sh

Должен стрелять каждый второй понедельник, начиная с 2018-03-19

Выражение гласит: бегите в 6 утра по понедельникам, если ...

1-Получить сегодняшнюю дату, в секундах, деленную на количество секунд в сутках, чтобы преобразовать в дни sice epoch

2-Сделайте то же самое для даты начала, преобразовав ее в число дней с момента начала эпохи

3-получить разницу между двумя

4-разделить на 14 и проверить остаток

5-если остаток равен нулю, вы находитесь на двухнедельном цикле.

Navneeth Shetty

07.02.2020 03:15:41

0 0 */14 * *

Работает в 00:00 каждый 14-й день месяца.

Закрыть X