program tip

매월 말일에 실행할 크론 작업

radiobox 2020. 9. 20. 09:22
반응형

매월 말일에 실행할 크론 작업


매월 말일에 실행할 크론 작업을 만들어야합니다. cpanel에서 만들겠습니다.

도움을 주시면 감사하겠습니다. 감사


아마도 가장 쉬운 방법은 세 가지 개별 작업을 수행하는 것입니다.

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

그러나 윤년에도 불구하고 2 월 28 일에 실행되므로 문제가 발생하면 다른 방법을 찾아야합니다.


그러나 일반적으로 다음과 같이 매월 1 일에 가능한 한 빨리 작업을 실행하는 것이 훨씬 쉽고 정확합니다 .

0 0 1 * * myjob.sh

그리고 처리 할 수있는 스크립트를 수정 이전 달의 데이터를.

이렇게하면 해당 월의 마지막 날을 파악하는 데 발생할 수있는 번거 로움이 제거되고 데이터를 처리한다고 가정 할 때 해당 월의 모든 데이터를 사용할 수 있습니다. 매월 마지막 날 5 분에서 자정까지 달리면 그 때부터 자정 사이에 발생하는 모든 것이 누락되는 것을 볼 수 있습니다.

이것은 대부분의 월말 작업에서이를 수행하는 일반적인 방법입니다.


당신은 여전히하면 정말 달의 마지막 날에 그것을 실행하려면, 하나의 옵션은 내일 (스크립트의 일부로하거나, 또는 crontab을 자체) 첫 번째 경우 단순히 감지하는 것입니다.

따라서 다음과 같습니다.

55 23 28-31 * * [[ "$(date --date=tomorrow +\%d)" == "01" ]] && myjob.sh

비교적 지능적인 date프로그램 이 있다고 가정하면 좋은 시작이 될 것 입니다.

귀하의 경우 date프로그램이 당신에게 상대 날짜를주는 아주 고급 충분하지, 당신은 (당신이 필요하지 않은 당신에게 달의 내일의 일을 제공하기 위해 함께 매우 간단한 프로그램을 넣을 수 있습니다 전체 의 힘을 date같은) :

#include <stdio.h>
#include <time.h>

int main (void) {
    // Get today, somewhere around midday (no DST issues).

    time_t noonish = time (0);
    struct tm *localtm = localtime (&noonish);
    localtm->tm_hour = 12;

    // Add one day (86,400 seconds).

    noonish = mktime (localtm) + 86400;
    localtm = localtime (&noonish);

    // Output just day of month.

    printf ("%d\n", localtm->tm_mday);

    return 0;
}

그런 다음 사용합니다 ( tomdom"내일의 날"로 불렀다고 가정 ).

55 23 28-31 * * [[ "$(tomdom)" == "1" ]] && myjob.sh

당신은 모두 이후 오류 검사를 추가하는 것을 고려할 수 있지만 time()mktime()반환 할 수 있습니다 -1뭔가 잘못되면. 위의 코드는 단순성 때문에이를 고려하지 않았습니다.


위의 방법 중 하나와 비슷하게 사용할 수있는 약간 더 짧은 방법이 있습니다. 그건:

[ $(date -d +1day +%d) -eq 1 ] && echo "last day of month"

Also, the crontab entry could be update to only check on the 28th to 31st as it's pointless running it the other days of the month. Which would give you:

0 23 28-31 * * [ $(date -d +1day +%d) -eq 1 ] && myscript.sh

Set up a cron job to run on the first day of the month. Then change the system's clock to be one day ahead.


What about this one, after Wikipedia?

55 23 L * * /full/path/to/command

Adapting paxdiablo's solution, I run on the 28th and 29th of February. The data from the 29th overwrites the 28th.

# 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

You could set up a cron job to run on every day of the month, and have it run a shell script like the following. This script works out whether tomorrow's day number is less than today's (i.e. if tomorrow is a new month), and then does whatever you want.

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

For a safer method in a crontab based on @Indie solution (use absolute path to date + $() does not works on all crontab systems):

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

Some cron implementations support the "L" flag to represent the last day of the month.

If you're lucky to be using one of those implementations, it's as simple as:

0 55 23 L * ?

That will run at 11:55 pm on the last day of every month.

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" 

00 23 * * * [[ $(date +'%d') -eq $(cal | awk '!/^$/{ print $NF }' | tail -1) ]] && job

Check out a related question on the unix.com forum.


For AWS Cloudwatch cron implementation (Scheduling Lambdas, etc..) this works:

55 23 L * ? *

Running at 11:55pm on the last day of each month.


You can just connect all answers in one cron line and use only date command.

Just check the difference between day of the month which is today and will be tomorrow:

0 23 * * * root [ $(expr $(date +\%d -d '1 days') - $(date +\%d)  ) -le 0 ]  && echo true

If these difference is below 0 it means that we change the month and there is last day of the month.


What about this?

edit user's .bashprofile adding:

export LAST_DAY_OF_MONTH=$(cal | awk '!/^$/{ print $NF }' | tail -1)

Then add this entry to crontab:

mm hh * * 1-7 [[ $(date +'%d') -eq $LAST_DAY_OF_MONTH ]] && /absolutepath/myscript.sh

55 23 28-31 * * echo "[ $(date -d +1day +%d) -eq 1 ] && my.sh" | /bin/bash 

참고URL : https://stackoverflow.com/questions/6139189/cron-job-to-run-on-the-last-day-of-the-month

반응형