![Запускать задание cron в первый понедельник каждого месяца?](https://rvso.com/image/1316111/%D0%97%D0%B0%D0%BF%D1%83%D1%81%D0%BA%D0%B0%D1%82%D1%8C%20%D0%B7%D0%B0%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5%20cron%20%D0%B2%20%D0%BF%D0%B5%D1%80%D0%B2%D1%8B%D0%B9%20%D0%BF%D0%BE%D0%BD%D0%B5%D0%B4%D0%B5%D0%BB%D1%8C%D0%BD%D0%B8%D0%BA%20%D0%BA%D0%B0%D0%B6%D0%B4%D0%BE%D0%B3%D0%BE%20%D0%BC%D0%B5%D1%81%D1%8F%D1%86%D0%B0%3F.png)
Я хотел бы запустить задание из cron в 8.30 в первый понедельник каждого месяца. На странице cron в Википедии говорится:
Хотя обычно задание выполняется, когда все поля спецификации времени/даты соответствуют текущему времени и дате, есть одно исключение: если и «день месяца», и «день недели» ограничены (не «*»), тоилиполе «день месяца» (3) или поле «день недели» (5) должно соответствовать текущему дню.
(выделено мной)
Означает ли это, что я не могу сделать это в первый понедельник месяца, я могу сделать это только в первый (или какой-то другой) день месяца? Я не могу придумать, как это обойти.
решение1
Вы можете поместить условие в фактическую команду crontab (общий способ):
[ "$(date '+%u')" = "1" ] && echo "It's Monday"
если ваша локаль EN/US, вы также можете сравнить строки (первоначальный ответ):
[ "$(date '+%a')" = "Mon" ] && echo "It's Monday"
Теперь, если это условие истинно в один из первых семи дней месяца, у вас есть его первый понедельник. Обратите внимание, что в crontab синтаксис процентов должен быть экранирован (общим способом):
0 12 1-7 * * [ "$(date '+\%u')" = "1" ] && echo "It's Monday"
если ваша локаль EN/US, вы также можете сравнить строки (первоначальный ответ):
0 12 1-7 * * [ "$(date '+\%a')" = "Mon" ] && echo "It's Monday"
Замените echo
команду на ту, которую вы хотите запустить. Я нашеланалогичный подходслишком.
решение2
У меня есть компьютер с испанской локалью, поэтому этот подход мне не подходит, потому чтопнизменения влунь
Другие языки тоже не справились бы, поэтому я немного изменил принятый ответ, устранив языковой барьер:
0 9 1-7 * * [ "$(date '+\%u')" = "1" ] && echo "¡Es lunes!"
решение3
Мне проще, когда нет необходимости иметь дело с номерами дней.
Запуск в первый понедельник месяца:
0 2 * * 1 [ `date '+\%m'` == `date '+\%m' -d "1 week ago"` ] || /path/to/command
т.е. если месяц 1 неделю назад не совпадает с текущим месяцем, то мы находимся в 1-м числе 1 (= понедельник) месяца.
Аналогично, для Третьей пятницы
0 2 * * 6 [ `date '+\%m'` == `date '+\%m' -d "3 weeks ago"` ] || /path/to/command
т.е. если месяц 3 недели назад отличается от текущего месяца, то мы находимся на 3-м дне 6-го числа (= пятница) месяца.
решение4
Я запланировал выполнение задания на четвертый понедельник каждого месяца в 16:00 следующим образом:
0 16 22-28 * Mon [ "$(date '+\%a')" == "Mon" ] && touch /home/me/FourthMonOfMonth.txt