14 ответов:
возможно, самый простой способ-просто выполнить три отдельных задания:
55 23 30 4,6,9,11 * myjob.sh 55 23 31 1,3,5,7,8,10,12 * myjob.sh 55 23 28 2 * myjob.shэто будет работать на 28 февраля, хотя, даже в високосные годы, так что, если это проблема, вам нужно будет найти другой способ.
однако, как правило, это и существенно проще и правильнее, чтобы запустить работу как можно скорее на первый числа каждого месяца, с чем-то вроде:
0 0 1 * * myjob.shи изменить сценарий для обработки данные за месяц.
это устраняет любые проблемы, с которыми вы можете столкнуться, выясняя, какой день является последним в месяце, а также гарантирует, что все данные за этот месяц доступны, предполагая, что вы обрабатываете данные. Бег за пять минут до полуночи в последний день месяца может привести к тому, что вы пропустите все, что произойдет между этим и полуночью.
это обычный способ сделать это в любом случае, для большинства конца месяца джобс.
если вы все-таки действительно хотите запустить его в последний день месяца, один из вариантов-просто определить, является ли завтра первым (либо как часть вашего скрипта, либо в самом crontab).
так, что-то вроде:
55 23 28-31 * * [[ "$(date --date=tomorrow +\%d)" == "01" ]] && myjob.shдолжно быть хорошее начало, предполагая, что у вас есть относительно умный
есть немного более короткий метод, который можно использовать аналогично одному из приведенных выше. То есть:
[ $(date -d +1day +%d) -eq 1 ] && echo "last day of month"кроме того, запись crontab может быть обновлена, чтобы проверить только с 28-го по 31-е, поскольку бессмысленно запускать ее в другие дни месяца. Что даст вам:
0 23 28-31 * * [ $(date -d +1day +%d) -eq 1 ] && myscript.sh
настроить cron для запуска на первый день месяца. Затем измените часы системы, чтобы быть на один день вперед.
адаптируя решение paxdiablo, я бегу на 28-й и 29 февраля. Данные из 29-го перезаписывает 28-й.
# min hr date month dow 55 23 31 1,3,5,7,8,10,12 * /path/monthly_copy_data.sh 55 23 30 4,6,9,11 * /path/monthly_copy_data.sh 55 23 28,29 2 * /path/monthly_copy_data.sh
вы можете настроить задание cron для запуска в каждый день месяца и запустить сценарий оболочки, как показано ниже. Этот скрипт определяет, будет ли завтрашний день меньше сегодняшнего (т. е. если завтра будет новый месяц), а затем делает все, что вы хотите.
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
00 23 * * * [[ $(date +'%d') -eq $(cal | awk '!/^$/{ print $NF }' | tail -1) ]] && jobпроверить вопрос на unix.com форум.
для более безопасного метода в crontab на основе решения @Indie (используйте абсолютный путь к
date+$()не работает на всех системах crontab):0 23 28-31 * * [ `/bin/date -d +1day +\%d` -eq 1 ] && myscript.sh
некоторые реализации cron поддерживают флаг " L " для представления последнего дня месяца.
Если вам повезло использовать одну из этих реализаций, это так же просто, как:
0 55 23 L * ?это будет работать в 11:55 вечера в последний день каждого месяца.
http://www.quartz-scheduler.org/documentation/quartz-1.x/tutorials/crontrigger
######################################################### # Memory Aid # environment HOME=$HOME SHELL=$SHELL LOGNAME=$LOGNAME PATH=$PATH ######################################################### # # string meaning # ------ ------- # @reboot Run once, at startup. # @yearly Run once a year, "0 0 1 1 *". # @annually (same as @yearly) # @monthly Run once a month, "0 0 1 * *". # @weekly Run once a week, "0 0 * * 0". # @daily Run once a day, "0 0 * * *". # @midnight (same as @daily) # @hourly Run once an hour, "0 * * * *". #mm hh Mday Mon Dow CMD # minute, hour, month-day month DayofW CMD #........................................Minute of the hour #| .................................Hour in the day (0..23) #| | .........................Day of month, 1..31 (mon,tue,wed) #| | | .................Month (1.12) Jan, Feb.. Dec #| | | | ........day of the week 0-6 7==0 #| | | | | |command to be executed #V V V V V V * * 28-31 * * [ `date -d +'1 day' +\%d` -eq 1 ] && echo "Tomorrow is the first today now is `date`" >> ~/message 1 0 1 * * rm -f ~/message * * 28-31 * * [ `date -d +'1 day' +\%d` -eq 1 ] && echo "HOME=$HOME LOGNAME=$LOGNAME SHELL = $SHELL PATH=$PATH"
как насчет этого?
редактировать пользователя
.bashprofileдобавляем:export LAST_DAY_OF_MONTH=$(cal | awk '!/^$/{ print $NF }' | tail -1)затем добавьте эту запись в crontab:
mm hh * * 1-7 [[ $(date +'%d') -eq $LAST_DAY_OF_MONTH ]] && /absolutepath/myscript.sh
для реализации cron AWS Cloudwatch (планирование лямбд и т. д..) это работает:
55 23 L * ? *работает в 11: 55 вечера в последний день каждого месяца.
Comments