Как планировать запуск первого воскресенья каждого месяца

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

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

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

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

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

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

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

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

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

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

Хакерное решение: каждое задание cron запускается каждое воскресенье, но ваш скрипт проверяет дату, когда он начинается, и немедленно выходите, если день месяца составляет> 7 …

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

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

Но,

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

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

Запуск задачи 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), если это правильная дата.

РЕДАКТИРОВАТЬ:

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

 # 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 

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

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

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

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

Вот почему вы видите рекомендацию использовать проверку [ ... ] с date чтобы установить такое правило: либо указать день недели в crontab, либо использовать [ и date чтобы проверить, месяц <= 7 перед запуском сценария, как показано в принятом ответе , или указав диапазон дня месяца в crontab и используя [ и date чтобы проверить день недели перед запуском, например:

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

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

  • Для сравнения используйте = , not == . Это более портативно, так как не все оболочки используют реализацию [ которая поддерживает оператор == .
  • Используйте спецификатор %u на date чтобы получить день недели как число, а не оператор %a , потому что %a дает разные результаты в зависимости от date локали.
  • Просто используйте date , не /bin/date или /usr/bin/date , так как утилита date имеет разные местоположения в разных системах.

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

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

Затем планируйте эту обертку для следующего первого воскресенья месяца. После этого он справится со всем.

Код будет чем-то вроде (акцент на что-то … проверка ошибок не выполняется):

 #! /bin/bash #We run your code first /path/to/your/code #now we find the next day we want to run nskip=28 #the number of days we want to check into the future curr_month=`date +"%m"` new_month=`date --date='$nskip days' +"%m"` if [[ curr_month = new_month ]] then ((nskip+=7)) fi date=`date --date='$nskip days' +"09:00AM %D` #you may need to change the format if you use another scheduler #schedule the job using "at" at -m $date < /path/to/wrapper/code 

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

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

попробуйте следующее

0 15 10? * 1 # 1

http://www.quartz-scheduler.org/documentation/quartz-1.x/tutorials/crontrigger

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

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

Interesting Posts
Давайте будем гением компьютера.