Выражение cron для выполнения во "второй последний рабочий день" месяца

Мне нужна ваша помощь, чтобы создать работу cron для запуска второго последнего рабочего дня каждого месяца. Я могу сделать LW, как показано ниже, но я не уверен, как сделать второй последний. Мне нужна ваша помощь и посоветуйте здесь, пожалуйста.

@MWE любезно предоставил мне возможное решение, но, похоже, оно не работает во всех тестовых сценариях.

code:
#!/bin/bash
date
WEEKDAY=$(date +%u)
# If detect the montday in 2 days.
if [ $(date +%d -d "2 day") -eq 1 ] && [ ${WEEKDAY} -lt 5 ] ; then
   echo "This is the 2. last working day of the month"
# If detect the montday in 5 days.
elif [ $(date +%d -d "5 day") -eq 1 ] && [ ${WEEKDAY} -eq 5 ] ; then
   echo "This is the 2. last working day of the month"
else
  exit
fi

Тестовый сценарий: я изменил системную дату на сервере на 29 августа 2019 года (** это вторая последняя рабочая дата в системе)

скрипт в режиме отладки завершается:

[oracle@rdbauroral01v ~]$ bash -x ./crontest.sh
+ date
Thu Aug 29 13:28:20 UTC 2019
++ date +%u
+ WEEKDAY=4
++ date +%d -d '2 day'
+ '[' 31 -eq 1 ']'
++ date +%d -d '5 day'
+ '[' 03 -eq 1 ']'
+ exit

ценим вашу помощь здесь..

5 ответов

Так же просто идея решить ее в скрипте, а не в crontab.

Последний день месяца всегда в этот день, когда завтра = 1. месяца.

Это значит: пусть вывести текущую дату из эпохи в секундах и добавить 24 часа. Тогда давайте выясним, какой это день месяца:

TIMESTAMP=$(date +%s)
TIMESTAMP_TOMORROW=$(( $TIMESTAMP + 86400 ))

Выясните день месяца завтрашнего дня:

DAYOFMONTH=$(date --date="@${TIMESTAMP_TOMORROW}" +%e)

если DAYOFMONTH == 1 сегодня последний день месяца. Делай, что хочешь, тогда. если нет == 1, выход.

Альтернативы можно найти здесь: https://stackoverflow.com/questions/6139189/cron-job-to-run-on-the-last-day-of-the-month

TODAY=`date +%d`
TOMORROW=`date +%d -d "1 day"`

# See if tomorrow's day is less than today's
if [ $TOMORROW -lt $TODAY ]; then
echo "This is the last day of the month"
# Do stuff...
fi

или же:

0 23 28-31 * * [ `/bin/date -d +1day +\%d` -eq 1 ] && myscript.sh

Последний, но тем не менее важный. Умножьте $(( $TIMESTAMP + 86400 * 2)) на 2. последний день.

или же:

TOMORROW=$(date +%d -d "2 day")

или же:

[ $(/bin/date -d +2day +\%d) -eq 1 ]

2. Выйти в последний рабочий день месяца. %u начать с первого дня в понедельник. %w с воскресеньем.

  1. последний рабочий день обычно четверг. Итак, 4. рабочий день. Мы должны смотреть сейчас 6 дней в будущее. -> Значит, последние 2. Рабочий день месяца должен быть до 5-го числа месяца.
WEEKDAY=$(date +%u)
TOMORROW=$(date +%d -d "5 day")
if [ ${WEEKDAY} -eq 4 ] && [ $TOMORROW -lt 5 ]; then
echo "This is the 2. last working day of the month"
fi

Нужно ли мне устанавливать задание cron как "0 0 20-31 * 1-5 ./scriptname"

Нет! Но имеет ли смысл выполнять его в любой день?

В crontab вы можете ограничить выполнение днями недели и месяцами. Оба в комбинации - хорошее начало. Таким образом, вы можете убедиться, что скрипт работает только в рабочий день. В месячный день в феврале (28 дней и т. Д.) Или всего 30 дней. это не заканчивается в 31 за каждый месяц! Поэтому, возможно, используйте день 20-31, чтобы быть в безопасности.

     field          allowed values
          -----          --------------
          minute         0-59
          hour           0-23
          day of month   1-31
          month          1-12 (or names, see below)
          day of week    0-7 (0 or 7 is Sunday, or use names)

Crontabentry, как:

0 0 20-31 * 1-5 ./scriptname

Часть легко узнать, какой второй третий или четвертый день недели. Почему? Скрипт запускается crontab только в рабочие дни. Таким образом, нас не заботит суббота или воскресенье. Альтернативно, мы могли бы проверить, равен ли Weekday $(date +%u) 1-5. Это рабочие дни.

Код теперь прост:

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

Вам нужно дело сейчас. С понедельника по четверг всегда будет следовать рабочий день. Таким образом, правила, если это через 2 дня 1. Месяц, это 2. Последний рабочий день. Только в пятницу должно быть первое число в 5 днях, чтобы быть вторым рабочим днем. Или первое число должно быть вторником.

WEEKDAY=$(date +%e)
# 1. If detect the montday in 2 days.
if [ $(date +%d -d "2 day") -eq 1 ] && [ ${WEEKDAY} -lt 5 ] ; then
   echo "This is the 2. last working day of the month"
# 1. If detect the montday in 5 days.
elif [ $(date +%d -d "5 day") -eq 1 ] && [ ${WEEKDAY} -eq 5 ]
   echo "This is the 2. last working day of the month"
else 
  exit
fi

Надеюсь, я ничего не пропустил.

Прочтите следующую статью, чтобы лучше понять типы выражений, разрешенные в cron:

В частности, в «День месяца», если вы укажете «28W» -> Либо он выполняется 28-го числа, либо, если 28-е число — суббота/воскресенье, оно будет выполняться в ближайший рабочий день (27-е, если 28-е — суббота, или 29-е, если 28-е — суббота). Воскресенье)

Ссылка: http://www.brightxpress.com/user/appendix/cron_expressions.htm .

Другие вопросы по тегам