cron jobs dow and mon exception - cron

Today 2017-25-09 and monday and I have seen a entry cron job in syslog. My crontab:
# m h dom mon dow user command
30 05 18 9 1 root /bin/bash [--job route--]
If today is 25th, why cron start job with dom to 18 ?

Its because you have both dow and dom set. Cron 'or's those together. Your cron job is starting on the 18th OR the 1st day of the week. So since today is the first day of the week its starting. If you dont want that to happen dont set DOW.
https://en.wikipedia.org/wiki/Cron

Related

Running a cron at 4 am and 4 pm

The following cron expression cron(0 14 ? * MON-FRI *) basically runs something 4:00 pm from Monday to Friday.
I am wondering if it is possible to modify the expression so I can run something at 4:00 am and 4:00 pm every Monday to Friday.
Use this crontab line to run command_name at 4:00 and 16:00 (4 AM and 4 PM) Monday-Friday:
0 4,16 * * 1-5 command_name
From crontab manual:
The time and date fields are:
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)
Your Cron job description looks different from the general crontab. But to give you an idea of how to achieve what you're looking for:
Edit cron-table. Choose your editor.
crontab -e
Add 2 lines cron jobs.
* 4 * * 1-5 /usr/bin/...# Your command goes here 04:00 am.
* 16 * * 1-5 /usr/bin/...# Your command goes here 04:00 pm.
4PM (16:00): 0 16 * * MON-FRI
See crontab guru
"At 16:00 on every day-of-week from Monday through Friday.”
4AM &4 PM (4:00 & 16:00): 0 4,16 * * MON-FRI
See crontab guru
β€œAt minute 0 past hour 4 and 16 on every day-of-week from Monday through Friday.”

Crontab executes at the wrong time

I have a crontab settings as follows:
sudo crontab -l -u bheng
Contents:
#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 Sun, or use names)
#
# m h dom mon dow command
MAILTO="bheng#outlook.com"
#Daily
01 22 * * * php /home/mysite.com/artisan products:exportdiff --interval="yesterday"
16 22 * * * php /home/mysite.com/artisan images:exportdiff --interval="yesterday"
31 22 * * * php /home/mysite.com/artisan publications:exportdiff --interval="yesterday"
#Weekly
1 23 * * 7 php /home/mysite.com/artisan publications:exportdiff --interval="last sunday"
16 23 * * 7 php /home/mysite.com/artisan images:exportdiff --interval="last sunday"
31 23 * * 7 php /home/mysite.com/artisan products:exportdiff --interval="last sunday"
As you can see, it suppose to be kicking at 10 and 11 PM at night.
But instead, I got 3 emails at 5 PM yesterday at 5:01 PM, 5:16 PM, 5:31 PM.
I thought it was the time wrong the in system or VM so I checked it I saw UTC time.
Then, I update it by running sudo dpkg-reconfigure tzdata and set it to US Eastern time.
Now, when I ran date command I got Ex.Thu Dec 15 07:56:27 EST 2016 correctly as US EST time.
Is there some service that I need to restart?
Or is this something other crontab settings that might have overwrite my current settings ?
I believe you have to restart cron after making time / time zone related changes.
Depending on your version of cron, you might be able to restart it with sudo service cron restart.

Set a cron every 10 days starting from 16th January

How to set a cron to execute every 10 days starting from 16th January? Would this suffice?
30 7 16-15/10 * * command >/dev/null
The above starts at 7.30 AM, 16th of every month and ends on next month 15th and repeats every 10 days. I don't think what I have above is correct. Can anyone tell me how to set up the cron so that month ends are taken into account and every 10 days the command is executed starting from 16th January this year 2016?.
As William suggested, cron can't handle this complexity by itself. However, you can run a cron job more frequently, and use something else for the logic. For example;
30 7 16-31 1 * date '+\%j' | grep -q '0$' && yourcommand
30 7 * 2-12 * date '+\%j' | grep -q '0$' && yourcommand
This date format string prints the day of the year, from 001 to 365. The grep -q will do a pattern match, NOT print the results, but return a success of a failure on the basis of what it finds. Every 10 days, the day of the year ends in a zero. On those days, yourcommand gets run.
This has a problem with the year roll-over. A more complex alternative might be to do a similar grep on a product of date '+%s' (the epoch second), but you'll need to do math to turn seconds into days for analysis by grep. This might work (you should test):
SHELL=/bin/bash
30 7 * * * echo $(( $(date '+%s') / 86400 )) | grep '0$' && yourcommand
(Add your Jan 16th logic too, of course.)
This relies on the fact that shell arithmetic can only handle integers. The shell simply truncates rather than rounding.
UPDATE
In a comment on another answer, you clarified your requirements:
The command should start executing on January 16th, and continue like on January 26th, February 5th, February 15th and so on – jai
For this, the epoch-second approach is probably the right direction.
% date -v1m -v16d -v7H -v30M -v0S '+%s'
1452947400
(I'm in FreeBSD, hence these arguments to date.)
SHELL=/bin/bash
30 7 * * * [[ $(( ($(date '+\%s') - 1452947400) \% 864000 )) == 0 ]] && yourcommand
This expression subtracts the epoch second of 7:30AM Jan 16 (my timezone) from the current time, and tests whether the resultant difference is divisible by 10 days. If it is, the expression evaluates true and yourcommand is run. Note that $(( 0 % $x )) evaluates to 0 for any value of $x.
This may be prone to error if cron is particularly busy and can't get to your job in the one second where the math works out.
If you want to make this any more complex (and perhaps even if it's this complex), I recommend you move the logic into a separate shell script to handle the date comparison math. Especially if you plan to add a fudge factor to allow for jobs to miss their 1-second window .. that would likely be multiple lines of script, which is awkward to maintain in a single cronjob entry.
Observation: the math capabilities of cron are next to non-existent. The math capabilities of the Unix tools are endless.
Conclusion: move the problem from the cron domain to the shell domain.
Solution: run this each day with 30 7 * * * /path/to/script in the crontab:
#!/bin/sh
PATH=$(/usr/bin/getconf PATH)
if test $(($(date +%j) % 10)) = 6; then
your_command
fi
This tests whether the day-of-year modulo 10 is 6, like it is for January 16 (and January 6th is already in the past...).
Thinking outside the box:
Fix your requirement. Convince whoever came up with that funny 10 day cycle to accept a 7 day cycle. So much easier for cron. This is following the KISS principle.
0 30 7 1/10 * ? * command >/dev/null
Output for the above express is,
Saturday, January 16, 2016 7:30 AM
1. Thursday, January 21, 2016 7:30 AM
2. Sunday, January 31, 2016 7:30 AM
3. Monday, February 1, 2016 7:30 AM
4. Thursday, February 11, 2016 7:30 AM
5. Sunday, February 21, 2016 7:30 AM
Output for your expression
i.e 30 7 16-15/10 * * command >/dev/null
2016-01-15 07:30:00
2016-02-15 07:30:00
2016-03-15 07:30:00
2016-04-15 07:30:00
2016-05-15 07:30:00
2016-06-15 07:30:00
2016-07-15 07:30:00
2016-08-15 07:30:00
2016-09-15 07:30:00
2016-10-15 07:30:00
The closest syntax would like this:
30 7 1-30/10 * *
30 7 1-31/10 * *
30 7 1-28/10 * *
30 7 1-29/10 * *
You can test the cron expression here http://cron.schlitt.info/

Every x days vs every xth day of the month

I have the following cron expression:
0 0 */30 * *
How come it still runs every 30th day of the month and not every 30 days starting from now? Having the expression:
0 0 30 * *
Yields the same run times:
2013-07-30 00:00:00
2013-08-30 00:00:00
2013-09-30 00:00:00
2013-10-30 00:00:00
2013-11-30 00:00:00
I think you might want to use at instead of cron. You can use at to schedule your script to run 30 days from now with the following:
at now +30 day /path/to/your/script
Then, just put the same line near the end of your script, to schedule it to run again 30 days later.

What is the syntax for a cron job that runs 15 and 45 minutes after the hour?

What is the syntax for a cron job that runs 15 and 45 minutes after the hour? (So every 30 minutes.)
Would the syntax be something like:
15,45,30 * * * * wget -O /dev/null http://somesite.com/4_leads.php
So for example it would run at
2:15
2:45
3:15
3:45
4:15
4:45
and so on
From man 5 crontab
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 Sun, or use names)
Or, in other words
# m h dom mon dow user command
15,45 * * * * yourusername wget -O /dev/null http://somesite.com/4_leads.php
Skip the username field if you place the entry in a user specific crontab, via crontab -e, crontab -e -u yourusername, or similar.
This question may be better suited to serverfault.

Resources