Как запланировать запуск первого воскресенья каждого месяца - PullRequest
49 голосов
/ 14 июля 2010

Я использую Bash на RedHat.Мне нужно запланировать запуск задания cron в 9:00 утра в первое воскресенье каждого месяца.Как я могу это сделать?

Ответы [ 10 ]

130 голосов
/ 14 июля 2010

Вы можете поместить что-то вроде этого в файл crontab:

00 09 * * 7 [ $(date +\%d) -le 07 ] && /run/your/script

date +%d дает вам номер текущего дня, а затем вы можете проверить, меньше или равен этот день 7. Если это так, введите команду.

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

Помните, что в файле crontab параметры форматирования для команды date должны быть экранированы.

12 голосов
/ 14 июля 2010

Вам нужно объединить два подхода:

a) Используйте cron для запуска работы каждое воскресенье в 9:00.

 00 09 * * 7     /usr/local/bin/once_a_week

b) В начале once_a_week вычислите дату и извлеките день месяца с помощью оболочки, Python, C / C ++, ... и теста, который находится в пределах от 1 до 7 включительно. Если это так, выполните настоящий скрипт; если нет, выйдите молча.

5 голосов
/ 15 июля 2018

Стоит отметить, что то, что выглядит как наиболее очевидный подход к этой проблеме, работает , а не .

Вы можете подумать, что вы можете просто написать запись в crontab, в которой указан день-внедельно 0 (для воскресенья) и день месяца 1-7, как здесь ...

# This does NOT work.
0 9 1-7 * 0 /path/to/your/script

... но из-за эксцентричность того, как Крон обрабатываетСтроки crontab с указанным днем ​​недели и днем ​​месяца , это не сработает, и фактически будет работать 1-го, 2-го, 3-го, 4-го, 5-го, 6-го и 7-го числамесяц (независимо от того, какой у них день недели) и в каждое воскресенье месяца.

Вот почему вы видите рекомендацию использовать [ ... ] проверьте с помощью date, чтобы установить подобное правило: либо укажите день недели в crontab, либо используйте [ и date, чтобы убедиться, чточисло дней месяца <= 7 перед запуском сценария, как показано в <a href="https://stackoverflow.com/a/3242169/1709587"> принятом ответе , или указание диапазона дня месяца в фронтеab и использование [ и date для проверки дня недели перед запуском, например:

# This DOES work.
0 9 1-7 * * [ $(date +\%u) = 7 ] && /path/to/your/script

Некоторые рекомендации, которые следует иметь в виду, если вы хотите, чтобы ваш crontabлиния будет работать независимо от того, в какой ОС вы ее используете:

  • Используйте для сравнения =, а не ==.Он более переносим, ​​поскольку не все оболочки используют реализацию [, которая поддерживает оператор ==.
  • Используйте спецификатор %u для date, чтобы получить число дня недели в виде числа, а не оператор %a, потому что %a дает разные результаты в зависимости от локали, в которой запускается date.
  • Просто используйте date, а не /bin/date или /usr/bin/date, так какУтилита date расположена в разных системах по-разному.
5 голосов
/ 31 марта 2014

Запустите задачу cron 1-го понедельника, 3-го вторника, последнего воскресенья, чего угодно ..

http://xr09.github.io/cron-last-sunday/

Просто поместите скрипт run-if-today в путь и используйте его с cron.

30 6 * * 6 root run-if-today 1 Sat && /root/myfirstsaturdaybackup.sh

Сценарий run-if-today вернет 0 (значение bash для True), если это правильная дата.

EDIT:

Теперь с более простым интерфейсом, только один параметр для номера недели.

# run every first saturday
30 6 * * 6 root run-if-today 1 && /root/myfirstsaturdaybackup.sh

# run every last sunday
30 6 * * 7 root run-if-today L && /root/lastsunday.sh
5 голосов
/ 14 июля 2010

Хакерское решение: пусть ваше задание cron запускается каждое воскресенье, но ваш скрипт проверяет дату при запуске и немедленно завершает работу, если день месяца> 7 ...

4 голосов
/ 25 октября 2013

Это также работает с именами дней недели:

0 0 1-7 * * [ "$(date '+\%a')" == "Sun" ] && /usr/local/bin/urscript.sh

Но,

[ "$(date '+\%a')" == "Sun" ] && echo SUNDAY

будет FAIL на командной строке из-заспециальная обработка "%" в crontab (также действует для https://stackoverflow.com/a/3242169/2919695)

0 голосов
/ 14 октября 2015
0 голосов
/ 18 апреля 2013

00 09 1-7 * 0 / usr / local / bin / Once_a_week

каждое воскресенье первых 7 дней месяца

0 голосов
/ 15 июля 2010

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

Код будет выглядеть примерно так:первое воскресеньеПоскольку мы начинаем в первое воскресенье текущего месяца, добавление 28 приведет нас либо к последнему воскресенью текущего месяца, либо к первому воскресенью следующего месяца.Если это текущий месяц, мы увеличиваем его до следующего воскресенья (которое будет в первую неделю следующего месяца).

И я использовал «в».Я не знаю, обманывает ли это.Основная идея - найти следующее первое воскресенье.После этого вы можете заменить любой планировщик, какой захотите, поскольку вы знаете дату и время, когда вы хотите запустить задание (хотя для другого планировщика может потребоваться другой синтаксис для этой даты).

0 голосов
/ 14 июля 2010

возможно, используйте cron.hourly для вызова другого скрипта. Затем этот скрипт проверит, будет ли это первое воскресенье месяца и 9 утра, и если да, запустите вашу программу. Звучит достаточно оптимально для меня: -).

...