Page 1 of 2 12 LastLast
Results 1 to 15 of 30
  1. #1
    Join Date
    Aug 2008
    Location
    Toronto, Canada
    Posts
    2,369

    Unanswered: crontab question

    I need to run a script every last Sat of every month. Something like:
    01 20 24-31 * 6 /etc/rc.stopportal #Stop Portal for Db2 reorg


    Is there a better/easier way to do the same? OS is AIX, Linux Intel and Z.

    Thanks.

  2. #2
    Join Date
    Jun 2003
    Location
    West Palm Beach, FL
    Posts
    2,713

    Talking

    Quote Originally Posted by db2girl View Post
    I need to run a script every last Sat of every month. Something like:
    01 20 24-31 * 6 /etc/rc.stopportal #Stop Portal for Db2 reorg

    Is there a better/easier way to do the same? OS is AIX, Linux Intel and Z.

    Thanks.
    Yes, Add this script to some directory (like /usr/src?):
    Code:
    #!/usr/bin/ksh
    # is_dow
    # get first/last day of month
    #-----------+-----------------------
    # Parameter | Description
    #-----------+-----------------------
    forl=$1     # First(F) or Last (L)?
    dow=$2      # Sun|Mon|Tue|Wed|Thu|Fri|Sat
    if [ $# -ne 2 ]
    then
      echo "Missing parameter(s)"
      echo "\t\t$0 Usage: 1-F/L {First or last} 2-Day {of the week}"
      exit 1
    fi
    tdy=`date +%a`
    typeset -u forl $forl
    typeset -u dow  $dow
    typeset -u tdy  $tdy
    if [ ! $dow = $tdy ]
    then
      echo 0
      exit 0
    fi
    cal|awk -v forl=$forl -v dow=$dow '
    BEGIN { d=index("SUN|MON|TUE|WED|THU|FRI|SAT|",dow); }
    NR < 3 {continue}
    {dw=int(substr($0,d,4));
     if(dw > 0) {
      if(d0 == 0) d0=dw
      d1=dw}
    } END {
    if(forl == "F") print d0;
    else if(forl == "L") print d1;
    else print 0; }'
    exit 0
    And use it in crontab like this:
    Code:
    01 20 24-31 * 6 [ `/usr/src/is_dow L Sat` -gt 0 ] && /etc/rc.stopportal #Stop Portal for Db2 reorg
    You owe me:
    PS: I don't think "...24-31 * 6 ..." alone will work...
    Last edited by LKBrwn_DBA; 05-03-12 at 17:16.
    The person who says it can't be done should not interrupt the person doing it. -- Chinese proverb

  3. #3
    Join Date
    Sep 2009
    Location
    Ontario
    Posts
    1,057
    Provided Answers: 1
    If you have access to ksh93 you could do it this way:
    Code:
    m=may
    y=2012
    printf "%T\n" "last sunday in $m $y" |read day month daynum time zone year
    today=`date +"%d"`
    if [ $today -eq $daynum ]
    then
      do_end_of_month
    else
      exit
    fi
    Last edited by kitaman; 05-03-12 at 20:03.

  4. #4
    Join Date
    Aug 2008
    Location
    Toronto, Canada
    Posts
    2,369
    Thank you, LKBrwn_DBA and kitaman



    Quote Originally Posted by LKBrwn_DBA View Post
    I don't think "...24-31 * 6 ..." alone will work...
    Why wouldn't it work? Assuming last Sat is the 24-31th day of the month. crontab didn't give me an error when I added this line (AIX/Linux). I think we had 28-29 last weekend and the scripts ran fine.


    ksh93 is not available on all servers so can't use kitaman's suggestion.

    LKBrwn_DBA's script is something I can definitely use if I can't get away without using any script.


    Thank you.

  5. #5
    Join Date
    Sep 2009
    Location
    Ontario
    Posts
    1,057
    Provided Answers: 1
    Why wouldn't it work?
    Because it will run every day from the 24th to the 31st and every Saturday.
    Note that the specification of days may be made by two fields
    (day of the month and day of the week). If both are specified as
    a list of elements, both are adhered to. For example, 0 0 1,15 *
    1 would run a command on the first and fifteenth of each month,
    as well as on every Monday. To specify days by only one field,
    the other field should be set to `` * '' (for example, 0 0 * * 1
    would run a command only on Mondays).
    Also Saturday could be as early as the 22nd in February.
    Just run it every Saturday and test in the script for the last Saturday.
    You could also create an annual calendar of the day of the year to run the job, and test to see if `date +"%j"` is in the list.
    List is "27,56,88, ...365") This way has the advantage of making adjustments for long weekends etc.

  6. #6
    Join Date
    Aug 2008
    Location
    Toronto, Canada
    Posts
    2,369
    Quote Originally Posted by kitaman View Post
    Because it will run every day from the 24th to the 31st and every Saturday.
    Didn't realize that day/month and day/week fields are OR'd. I was hoping to do it without using any additional scripts. Some scripts have to run on the first/last Sat, some first/last Sun...


    Quote Originally Posted by kitaman View Post
    You could also create an annual calendar of the day of the year to run the job, and test to see if `date +"%j"` is in the list.
    List is "27,56,88, ...365") This way has the advantage of making adjustments for long weekends etc.
    This is too complicated for me. I'll test LKBrwn_DBA's script.


    Thank you!

  7. #7
    Join Date
    Jun 2003
    Location
    West Palm Beach, FL
    Posts
    2,713

    Cool

    Quote Originally Posted by kitaman View Post
    ... Etc ...
    You could also create an annual calendar of the day of the year to run the job, and test to see if `date +"%j"` is in the list.
    That is why I use the built-in "cal" function.
    The person who says it can't be done should not interrupt the person doing it. -- Chinese proverb

  8. #8
    Join Date
    Sep 2009
    Location
    Ontario
    Posts
    1,057
    Provided Answers: 1
    and kitaman
    Rudy and I have been known to imbibe at a quiet restaurant at Don Mills and Eglinton.

  9. #9
    Join Date
    Aug 2008
    Location
    Toronto, Canada
    Posts
    2,369
    Quote Originally Posted by kitaman View Post
    Rudy and I have been known to imbibe at a quiet restaurant at Don Mills and Eglinton.
    to kitaman from Toronto.

  10. #10
    Join Date
    Aug 2008
    Location
    Toronto, Canada
    Posts
    2,369
    Quick question please. I should specify * instead of 24-31 in crontab, right?

    01 20 24-31 * 6 [ `/usr/src/is_dow L Sat` -gt 0 ] && /etc/rc.stopportal #Stop Portal for Db2 reorg

  11. #11
    Join Date
    Sep 2009
    Location
    Ontario
    Posts
    1,057
    Provided Answers: 1
    Yes. That way the job will run every Saturday. The script itself should decide if it is the correct Saturday.

  12. #12
    Join Date
    Aug 2008
    Location
    Toronto, Canada
    Posts
    2,369
    Merci, Mr. Toronto

  13. #13
    Join Date
    Aug 2008
    Location
    Toronto, Canada
    Posts
    2,369
    My crontab entry looks like:
    01 00 * * 0 [ `/sis/db2/db2inst1/scripts/R3/is_dow.ksh L Sun` -gt 0 ] && /sis/db2/db2inst1/scripts/R3/R3.ksh


    R3.ksh ran on Jun 24th as expected.

    But it also ran this Sun, July 1st. The server time is local (EST) and I verified that the time is set correctly.



    This is what it returns for July:

    $ ./is_dow.ksh L Sun
    29

    $ ./is_dow.ksh F Sun
    1


    Could you please help me figure out what went wrong?

  14. #14
    Join Date
    Sep 2009
    Location
    Ontario
    Posts
    1,057
    Provided Answers: 1
    Is the is_dow.ksh script still as originally posted.
    If so, the output is a number between 1 and 31, so testing for it being greater than zero (in your crontab entry) is always true.
    The only time the script prints zero is if parameter 1 is not F or L (for cobol) or not F and L for others.
    By the way, I added two input fields to the script, month (01-12) and year so that you can run it for any month, not just the current one.
    Code:
    #!/usr/bin/ksh                                                   
    # is_dow                                                         
    # get first/last day of month                                    
    #-----------+-----------------------                             
    # Parameter | Description                                        
    #-----------+-----------------------                             
    forl=$1     # First(F) or Last (L)?                              
    dow=$2      # Sun|Mon|Tue|Wed|Thu|Fri|Sat                        
    month=$3    # Calendar month (01-12)                             
    year=$4     # Calendar year                                      
    if [ $# -ne 4 ]                                                  
    then                                                             
      echo "Missing parameter(s)"                                    
      echo "\t\t$0 Usage: 1-F/L {First or last} 2-Day {of the week}" 
      echo "\t\t$0        3-Month of year (01-12), 4-Year YYYY"      
      exit 1                                                         
    fi                                                               
    tdy=`date +%a`                                        
    typeset -u forl $forl                                 
    typeset -u dow  $dow                                  
    typeset -u tdy  $tdy                                  
    if [ ! $dow = $tdy ]                                  
    then                                                  
      echo 0                                              
      exit 0                                              
    fi                                                    
    cal $month $year|awk -v forl=$forl -v dow=$dow '      
    BEGIN { d=index("SUN|MON|TUE|WED|THU|FRI|SAT|",dow); }
    NR < 3 {continue}                                     
    {dw=int(substr($0,d,4));                              
     if(dw > 0) {                                         
      if(d0 == 0) d0=dw                                   
      d1=dw}                                              
    } END {                                               
    if(forl == "F") print d0;                             
    else if(forl == "L") print d1;                        
    else print 0; }'

  15. #15
    Join Date
    Sep 2009
    Location
    Ontario
    Posts
    1,057
    Provided Answers: 1
    Something else that I noticed is the output of "cal"
    on Linux
    Code:
    cgc7:~ # cal          
          July 2012       
    Su Mo Tu We Th Fr Sa  
     1  2  3  4  5  6  7  
     8  9 10 11 12 13 14  
    15 16 17 18 19 20 21  
    22 23 24 25 26 27 28  
    29 30 31
    on SCO, and presumably AIX (System V Unix)
    Code:
    # cal                                                               
    Sun Jul 01 13:20:29 2012                                            
             Jun                    Jul                    Aug          
    Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa  
                    1  2             1  2  3  4  5  6  7                        1  2  3  4  
      3  4  5  6    7  8   9         8  9 10 11 12 13 14          5  6  7  8  9 10 11  
    10 11 12 13 14 15 16   15 16 17 18 19 20 21     12 13 14 15 16 17 18  
    17 18 19 20 21 22 23   22 23 24 25 26 27 28     19 20 21 22 23 24 25  
    24 25 26 27 28 29 30   29 30 31                      26 27 28 29 30 31
    Whereas
    #cal mo# year
    produces the same output on Linux and Unix.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •