Cron scheduling from whole hour to half - cron

I faced with problem. I need to set cron scheduler to start every day every minute from 8 AM to 10:30PM. Who knows, is it possible?

Crontab files give some form of flexibility to define periodic tasks, but in some instances, they are rigid and need some massaging to get the job done. The case presented by the OP is such as case.
Set up a cron-job which runs every minute, every day, but do it only from time tStart up to and including tEnd
Below you find multiple cases which allow you to perform the requested tasks in multiple intervals:
# .----------------------- minute (0 - 59)
# | .--------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7)
# | | | | |
# * * * * * command to be executed
# --------------------------------------------------------------
* 8-21 * * * command1 # daily [08:00, 21:59]
# --------------------------------------------------------------
* 8-21 * * * command2 # daily [08:00, 21:59]
0 22 * * * command2 # daily [22:00, 22:00]
# --------------------------------------------------------------
17-59 8 * * * command3 # daily [08:17, 08:59]
* 9-21 * * * command3 # daily [09:00, 21:59]
0-33 22 * * * command3 # daily [22:00, 22:33]
# --------------------------------------------------------------
* * * * * /path/testcmd 08:30 22:30 && command4
Here, command1 will execute every minute from 08:00 up to and including 21:59. command2 is identical to command1 but the extra line also includes 22:00. command3 has a somewhat more complex form that allows a general time-frame.
While it is possible to define complex cases using multiple lines, it makes maintenance a bit cumbersome. It is than also often useful, in case of complex cases to make use of a conditional command that allows you to perform date-time checks command4 is such a case. This command will only be executed if the command /path/testcmd 08:30 22:30 has a non-zero return-status. The testcmd could be quickly written as:
#!/usr/bin/env bash
tStart="$1"
tEnd="$2"
tNow="$(date "+%H:%M")"
# Lexicographical comparison
[ "$tStart" <= "$tNow" ] && [ "$tNow" <= "$tEnd" ]

Related

CRON with AND relationship between mday and wday

I have seen this question which indicates that the relationship between the wday and mday fields of a CRON schedule is an OR relationship. Say for example I want to schedule something for every Friday the 13th.
Rather than the expected result, the CRON
0 0 13 * 5
will give me all Fridays of every month, as well as every 13th of every month.
Is there any way to avoid this behavior and specify an AND relationship? (There seems to be mention of older versions using an AND relationship, however I would prefer to use a single tool with the ability to do both)
I guess, instead of specifying the wday (Friday=5), you'll just have to specify the months where the 13th is a Friday; so, for 2019:
0 0 13 9,12 * : do stuff, but avoid black cats
Or, eternally more elegant, create a small script:
$> cat /home/me/bin/test_friday_13
#!/bin/bash
if [ "$(date +'%A %d')" != "Friday 13" ]
then
exit 1
else
: do stuff, but avoid black cats
exit 0
fi
and make the crontab entry:
0 0 13 * * /home/me/bin/test_friday_13
The script approach has the added benefit that you can run it from the command line. (Note: do not forget to alter the weekday name in the script to reflect your environment.)
The cron-entry you are interested in is:
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7)
# | | | | |
# * * * * * command to be executed
0 0 13 * * [ $(date "+\%u") = "5" ] && command
This will execute the cronjob every 13th of the month. It will compute the day of the week, and test it if it is a Friday (5). If so, it will execute command.
Extended explanation:
If you want to have special conditions, you generally need to implement the conditions yourself with a test. Below you see the general structure:
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7)
# | | | | |
# * * * * * command to be executed
0 0 13 * * /path/to/testcmd && command
The command testcmd generally returns exit code 0 if the test is successful or 1 if it fails. If testcmd is successful, it executes command. A few examples that use similar tricks are in the following posts:
Linux crontab for nth Satuday of the month
Is it possible to execute cronjob in every 50 hours?
Cron expression to run every N minutes
how to set cronjob for 2 days?
The test you want to perform is written in /bin/sh as:
[ $(date "+%u") = 5 ]
Which makes use of the test command (see man test). This is POSIX compliant and will work with any shell that your cron might run in (sh,bash,dash,ksh,zsh). The command date "+%u" returns the weekday from 1 to 7 (Sunday is 7). See man date for more info.
So your cronjob would look like:
0 0 13 * * [ $(date "+\%u") = 5 ] && command
Note that we have to escape the <percent>-character.
A % character in the command, unless escaped with a backslash (\), will be changed into newline characters, and all data after the first % will be sent to the command as standard input.
source: man 5 crontab
Unfortunately, CRON doesn't work the way you want
You can see all available options on below url
https://www.freeformatter.com/cron-expression-generator-quartz.html
So what you can do is the execute the cron on every 13th of the month but don't let the command run when its Friday
0 0 0 13 * ? * mybatchjob.sh
mybatchjob.sh
if [ `date +'%A'` = "Friday" ]; then
echo "Yep its Friday";
else
echo "Not Friday";
fi
This will make sure that the intended program only runs on Friday and the 13th

cron at 15,55 and 35 every other hour

first are these cron anyway similar and if so which ones are redundant?
a) 15,35,55 * * * *
b) 15,35,55 */1 * * *
c) 15,35,55 0/1 * * *
What would be the cron to run at 35 and 15min/55min interchanged by an hour?
e.g
8am - 9am: 8:35am
9am - 10am: 9:15am and 9:55am
10am - 11am: 10:35am
11am - 12am: 11:15am and 11:55am
e.t.c
If you want to know what your cron is doing, then you can easily use crontab-guru to verify.
On your first question, yes the three examples are identical. The manual states the following :
man 5 crontab: Step values can be used in conjunction with ranges. Following a range with /<number> specifies skips of the
number's value through the range. For example, 0-23/2 can be used
in the 'hours' field to specify command execution for every other hour
(the alternative in the V7 standard is
0,2,4,6,8,10,12,14,16,18,20,22). Step values are also permitted
after an asterisk, so if specifying a job to be run every two hours,
you can use */2.
See the following examples:
# Example of job definition:
# .-------------------------- minute (0 - 59)
# | .----------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7)
# | | | | |
# * * * * * command to be executed
15,35,55 * * * * command1
15,35,55 */1 * * * command2
15,35,55 0/1 * * * command3
15,35,55 0-23/1 * * * command4
So in the above example, command[1-4] will be executed at the same time, every hour on minute 15, 35 and 55
For your second question, it is best done this way :
# Example of job definition:
# .------------------------ minute (0 - 59)
# | .----------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr .
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7)
# | | | | |
# * * * * * command to be executed
15 0/2 * * * command1
35,55 1/2 * * * command1
15 8/2 * * * command2
35,55 9/2 * * * command2
15 8-18/2 * * * command3
35,55 9-18/2 * * * command3
Here, command1 will execute on {00,02,04,06,...,22}:15 and {01,03,05,...,23}:{35,15}, command2 will execute on {08,10,...,22}:15 and {09,11,...,23}:{35,15} and command3 will execute on {08,10,...,18}:15 and {09,11,...,17}:{35,15}.

Is it possible to execute cronjob in every 50 hours?

I've been looking for a cron schedule that executes a script for every 50 hours. Running a job for each 2 days is simple with cron. We can represent like
0 0 */2 * * command
But what about every 50 hours?
If you want to run a cron every n hours, where n does not divide 24, you cannot do this cleanly with cron but it is possible. To do this you need to put a test in the cron where the test checks the time. This is best done when looking at the UNIX timestamp, the total seconds since 1970-01-01 00:00:00 UTC. Let's say we want to start from the moment McFly arrived in Riverdale:
% date -d '2015-10-21 07:28:00' +%s
1445412480
For a cronjob to run every 50th hour after `2015-10-21 07:28:00', the crontab would look like this:
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7)
# | | | | |
# * * * * * command to be executed
28 * * * * hourtestcmd "2015-10-21 07:28:00" 50 && command
with hourtestcmd defined as
#!/usr/bin/env bash
starttime=$(date -d "$1" "+%s")
# return UTC time
now=$(date "+%s")
# get the amount of hours
hours=$(( (now - starttime) / 3600 ))
# get the amount of remaining minutes
minutes=$(( (now - starttime - hours*3600) / 60 ))
# set the modulo
modulo=$2
# do the test
(( now >= starttime )) && (( hours % modulo == 0 )) && (( minutes == 0 ))
Remark: UNIX time is given in UTC. If your cron runs in a different time-zone which is influenced by daylight saving time, it could lead to programs being executed with an offset or when daylight saving time becomes active, a delta of 51hours or 49hours.
Remark: UNIX time is not influenced by leap seconds
Remark: cron has no sub-second accuracy
Remark: Note how I put the minutes identical to the one in the start time. This to make sure the cron only runs every hour.

How to specify a file to run everyday in crontab

I wants to run a file by everyday using crontab. But i have confusion on specifying the file in crontab. So, please suggest me to mention the file to run everyday ( start of the day, for example: 12:00 am ). Thanks in advance.
If by "file" you mean an executable shell script, then this will do:
00 00 * * * /path/to/the/executable/file.sh
It will run at midnight every day. You should enter this line in a file that will open when you invoke crontab -e command. Once you edit it, save and quit, and crontab will verify whether syntax you entered is correct, so watch the output in the shell.
Use the following format:
0 0 * * * command
check examples here
# minute, hour, day of month, month, day of week
* 12 * * * /home/mydirectory/myscript.sh
* 23 * * * /home/mydirectory/myotherscript.sh
58 23 * * * /home/mydrectory/two_minutes_to_midnight.sh
* 0 * * * /home/mydirectory/goodnight.sh
to make a crontab work, you can read an official doc, there are many of them, and depends on you operational system. But speaking od rules? i'll give some examples:
Common rules :
############################################################################
#
# * * * * * running command
# - - - - -
# | | | | |
# | | | | ----- day of week (0 - 7) (sunday =0 or =7)
# | | | ------- month (1 - 12)
# | | --------- day (1 - 31)
# | ----------- hour (0 - 23)
# ------------- minute (0 - 59)
#
###########################################################################
So if you want to call shell script that works with your files every "x" minutes you can make such a rule :
# work every two minutes
*/2 * * * * /usr/local/sbin/work_script.sh
also, between ranges:
# works every 5 minutes between 7 and 22 hours
*/5 7-22 * * * /usr/local/sbin/work.sh
You can use the below command to intialize the crontab entry to run it everyday.
Syntax : * 10 * * * /home/nagios/myscript.sh
Add the entry #crontab -e and save.
The above command will the command daily at 10 am in the morning.

cron expression for every > 60 minutes job

Is there any way to design the cron expression as to run every 70 minutes or 210 minutes i.e. > 60 minutes. I tried to search for this, but was not able to find this.
I finally went with a wrapper script that would do the required time checking which was called every 5 minutes(or the optimal recurring time).
How to accomplish such task in cron expression ?
Run every 70 minutes
* */1.1666
or
Run every 210 minutes
* */3.5
Basically, you need to run your cron every minute:
* * * * *
and let your script determine if its last execution dates from 70 or 210 minutes ago.
If it does, it would go on with the rest of the script.
If it does not, it would exit immediately.
In other words, don't try and put everything in the cron expression.
As commented by Keith Thompson, you could instead run that script less often (0 0/5 0 ? * * *), with a test at 70 minutes, or every 30 minutes (0 0/30 0 ? * * *) with a test at 210 minutes.
This answer is fairly identical to this and this
If you want to run a cron every n minutes, there are two cases to consider :
Every nth minute (60 is divisible by n)
Every nth minute starting from YYYY-MM-DD HH:MM:00 (generic)
The later covers the OP's case, but to remain generic I present both cases.
Every nth minute (60 is divisible by n)
This is valid for (n=1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30)
For this we use the combination of defining a range and a step value:
man 5 crontab: Step values can be used in conjunction
with ranges. Following a range with /<number> specifies
skips of the number's value through the range. For example,
0-23/2 can be used in the 'hours' field to specify command
execution for every other hour (the alternative in the V7
standard is 0,2,4,6,8,10,12,14,16,18,20,22). Step values are
also permitted after an asterisk, so if specifying a job to be
run every two hours, you can use */2.
See the following example:
# Example of job definition:
# .----------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7)
# | | | | |
# * * * * * command to be executed
m/n * * * * command1
Here, command1 will be executed every nth minute from m till 59.
This means that :
if m<=n, they will always be spaced by n minutes.
Eg. m=2,n=10 :: the job will run on minutes 2,12,22,32,42,52
if m>n, they will always be spaced by n minutes, except at the
start of the hour.
Eg. m=12,n=10 :: the job will run on minutes
12,22,32,42,52. So here we have a jump of 20 minutes between
the 52nd and 12th minute.
note: you clearly see that if n does not divide 60
perfectly, you will have problems. Eg. m=0,n=11 runs on
0,11,22,33,44,55, so we only have 5 minutes to the next run.
Every nth minute starting from YYYY-MM-DDTHH:MM:00
If you want to run a cron every n minutes, you cannot do this cleanly with cron but it is possible. To do this you need to put a test in the cron where the test checks the time. This is best done when looking at the UNIX time stamp, the total seconds since 1970-01-01 00:00:00 UTC. Let's say we want to start from the moment McFly arrived in Riverdale:
% date -u -d '2015-10-21 07:28:00' +%s
1445412480
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7)
# | | | | |
# * * * * * command to be executed
* * * * * mintestcmd "2015-10-21 07:28:00" 7 && command1
*/10 * * * * mintestcmd "2015-10-21 07:00:00" 70 && command2
*/30 * * * * mintestcmd "2015-10-21 07:00:00" 210 && command3
with mintestcmd defined as
#!/usr/bin/env bash
starttime=$(date -d "$1" "+%s")
# return UTC time
now=$(date "+%s")
# get the amount of minutes
delta=$(( (now - starttime) / 60 ))
# set the modulo
modulo=$2
# do the test
(( delta >= 0 )) && (( delta % modulo == 0))
In the above examples we have:
command1 will run every 7 minutes on 2015-10-21 07:28:00, 2015-10-21 07:35:00, 2015-10-21 07:42:00, 2015-10-21 07:49:00, ...
command2 will run every 70 minutes from 2015-10-21 07:00:00 onwards. Since 70 is divisible by 10 and the start-time starts perfectly on the hour, we can set the cron to run every 10 minutes.
command3 will run every 210 minutes from 2015-10-21 07:00:00 onwards. Since 210 is divisible by 30 and the start-time starts perfectly on the hour, we can set the cron to run every 30 minutes.
Remark: UNIX time is given in UTC. If your cron runs in a
different time-zone which is influenced by daylight saving
time, it is advisable not to run the command between 2 and 3
o'clock. This could skip the command or run the command
twice (depending upon whether the time jumps forward or backwards)
Remark: UNIX time is not influenced by leap seconds
Remark: cron has no sub-second accuracy

Resources