Обязательно ли 31 означает конец месяца в работе cron?

13

Для работы cron мы знаем, что можем установить время, как показано ниже.

# +------------ Minute (0 - 59)
# | +---------- Hour (0 - 23)
# | | +-------- Day of the Month (1 - 31)
# | | | +------ Month (1 - 12)
# | | | | +---- Day of the Week (0 - 7) (Sunday is 0 or 7)
# | | | | |
# * * * * * command

Что я хочу знать, так это то, что когда мы устанавливаем день месяца 31, означает ли это конец каждого месяца, хотя у месяца нет дня 31. Надеюсь получить ответ.

заранее спасибо

squillman
источник

Ответы:

22

Нет, 31 означает 31.

Тем не менее, вы можете сделать некоторые хитрости. Задайте задание на запуск в любой день, который потенциально может быть последним днем ​​месяца (т. Е. 28-31 в поле дня месяца), а затем замените вашу команду выражением оболочки, содержащим тест на дату, защищающую команда:

0 0 28-31 * * [ "`date +%m`" != "`date --date=tomorrow +%m`" ] && command

Выражение внутри тестовых скобок просто спрашивает, отличается ли номер месяца сегодня от номера месяца завтра, что, конечно, будет верно только в последний день месяца. Обратите внимание, что форма этого выражения зависит от вашего локального date- вам может понадобиться настроить его, если у вас нет текущей версии GNU.

Я должен сказать, что я не изобрел это - я нашел это с быстрым Google в сообщении списка рассылки Мэтью Джарвисом. Хотя я бы предположил, что это очень стандартный трюк старого мастера Unix.

Том Андерсон
источник
1
Это не может быть слишком старым трюком, учитывая специфические для GNU опции «date» =)
jj33
4
На сайтах stackexchange задание вопроса, на который можно найти с помощью поиска Google, НЕ является плохой вещью. На самом деле это хорошо, так как следующий человек, который будет искать это в Google, найдет ответ на stackexchange и придет сюда.
Мирник
12

Нет, я думаю, что лучшее, что вы можете сделать, это запустить в полночь 1-го числа месяца или настроить отдельные строки crontab для каждого месяца (или, по крайней мере, строку для месяцев с 28, 29, 30 и 31 днем).

0 0 28,29 2               * /my/command
0 0 30    4,6,9,11        * /my/command
0 0 31    1,3,5,7,8,10,12 * /my/command
Пол Диксон
источник
Спасибо, Пол! Я буду следовать за вторым. Для второго метода мне нужно установить один и тот же файл три раза, верно? Еще раз спасибо :)
Да, вам нужно будет повторить это.
Пол Диксон
7
У меня нет опыта работы с cron, но разве «0 0 28,29 2» не будет выполняться дважды в високосный год? Не то чтобы это было проблемой в течение следующих двух лет, но все же ...
Вим тен Бринк
Это хороший момент, нелегкий путь
Пол Диксон
4

Я не думаю, что вы можете сделать это легко в crontab.

Один из вариантов - установить cronзапуск сценария каждый день, а затем заставить сам скрипт проверять, является ли он последним днем ​​месяца.

Дэйв Уэбб
источник
3

Я предполагаю, что у cron есть специальный символ 'L', предназначенный для этой цели:

*    *    L    *    *    your_script.sh 

выполнит ваш скрипт в последний день каждого месяца

С другой стороны,

*    *    0    *    *    your_script.sh

Вы даже можете указать что-то вроде:

*    *    *    *    1,5L    your_scrript.sh

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

или

*    *    *    *    1    your_script.sh

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

Saasira
источник
0

Это сделает работу:

if [ $( date +%-d --date="tomorrow" ) -eq 1 ]
then echo Last day of the current month
else echo Not yet!
     exit 0
fi

exit 1
Фил
источник