How do I set up a cronjob that runs every 25th hour?
Just a guess, but you don't
Best hack off the top of my head: write a script to track the last time it was run, and conditionally run it if it was more than 25 hours ago.
Cron that driver script to run every hour.
It would be easier to issue an at command specifying the time and date of the next job when you start the current one but you could simulate that with a cronjob by updating the cronjob entry for the process at the start of the current run (not at the end 'cos then you'd have to take into account the time to run the job).
Setup a hourly job and check in your script if 25 hours are past with this snipnet:
if [ $((((`date +%s` - (`date +%s` % 3600))/3600) % 25)) -eq 0 ] ; then
your script
fi
You can achieve any frequency if you count the hours(, minutes, days, or weeks) since Epoch, add a condition to the top of your script, and set the script to run every hour on your crontab:
#!/bin/bash
hoursSinceEpoch=$(($(date +'%s / 60 / 60')))
# every 25 hours
if [[ $(($hoursSinceEpoch % 25)) -ne 0 ]]; then
exit 0
fi
date(1) returns current date, we format it as seconds since Epoch (%s) and then we do basic maths:
# .---------------------- bash command substitution
# |.--------------------- bash arithmetic expansion
# || .------------------- bash command substitution
# || | .---------------- date command
# || | | .------------ FORMAT argument
# || | | | .----- formula to calculate minutes/hours/days/etc is included into the format string passed to date command
# || | | | |
# ** * * * *
$(($(date +'%s / 60')))
# * * ---------------
# | | |
# | | ·----------- date should result in something like "1438390397 / 60"
# | ·-------------------- it gets evaluated as an expression. (the maths)
# ·---------------------- and we can store it
And you may use this approach with minutely, hourly, daily, or monthly cron jobs:
#!/bin/bash
# We can get the
minutes=$(($(date +'%s / 60')))
hours=$(($(date +'%s / 60 / 60')))
days=$(($(date +'%s / 60 / 60 / 24')))
weeks=$(($(date +'%s / 60 / 60 / 24 / 7')))
# or even
moons=$(($(date +'%s / 60 / 60 / 24 / 656')))
# passed since Epoch and define a frequency
# let's say, every 13 days
if [[ $(($days % 13)) -ne 0 ]]; then
exit 0
fi
# and your actual script starts here
You could use the 'sleep' or 'watch' commands to have a script run in a loop. Just make sure you script is executed.
I think you should try this
0 */25 * * * ...
Related
Is it possible to have a cronjob run every 15 minutes (over every hour etc..) except for at 3AM?
I have another special cronjob I want to run at 3AM, but I don't want the other one to run at the same time...
With one cron line, no. With three, yes:
# Every 15 minutes except for 3:00-3:59
*/15 0-2,4-23 * * * thejob
# 3:15, 3:30, 3:45
15-45/15 3 * * * thejob
# 3:00 dead
0 3 * * * otherjob
I made my own solution, but I wanted to see what other people thought of!
I put this on the top of my desired script. I wanted it to not run at the half hour either so it doesn't do it on both.
On top of the script:
if [ $(date +%M) = 00 ] || [ $(date +%M) = 30 ]
then
exit
fi
The cron line:
*/15 * * * * ~/path/to/file
Hope anyone uses my solution too.
0,15,30,45 0,1,2,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23 * * * your cron job
I found a interesting thing during creation of my crontab setting.
I used this command:
crontab -e
and fill this line:
*/55 * * * * export DISPLAY=:0 && /home/user/Documents/script.sh $2>/dev/null
My idea was create scheduler, which start script.sh every 55 minutes.
But this script is execute in this times (for example):
08:55, 09:00, 09:05, 09:55, 10:00, 10:05, ...
and I don't know why.
Can someone explain me that?
Replace the script like this and it should work.
*/5 * * * * [ $(( $(date +%s) / 60 % 55 )) -eq 0 ] && export DISPLAY=:0 && /home/user/Documents/script.sh $2>/dev/null
minute-hour-day-month-year
* any value
, value list separator
- range of values
/ step values
Another option is a self-replicating 'at' job. Only advantage over cron is that it is less obvious, and also if you needed it to kick off not every X minutes, but X minutes after the last job completed. So your script will just contain a line to create a new 'at' job before it exits. Something like:
echo "/full/path/to/my/script > /root/myScript.at.log" | at now + X minutes
so every 5 minutes it will do this:
number of seconds elapsed since 1. 1. 1970 will divided by 60 = how many minutes
echo $(date +%s)
1476201056 ... second
echo $(( $(date +%s) / 60 ))
24603351 ... minutes
after that it will use modulo on count of minutes
When result of modulo is 0, it will send TRUE value.
And it is a typical logical AND
[ $((......)) -eq 0 ] && export DISPLAY.. && .../script.sh
Thank you.
It is really helpful :)
Hey I got crontab that runs every 5 minutes and it looks like this
*/5 * * * * blablalba
How can I get it running every 5 minutes and 30 seconds?
Instead of using Cron, have your script re-start itself using this as the final line:
echo /path/to/script | at now + 330 seconds
Or to be more "precise" in the timing : take into accoutn how many seconds you spend running the script and take those out of the 330 seconds (5mn and 30s) :
#beginning of script
seconds_at_start=$(date +%s)
....
#end of script
seconds_at_end=$(date +%s)
nb_seconds=$((330 + seconds_at_start - seconds_at_end))
echo /path/to/script | at now + $nb_seconds seconds
Note: you may want to use bc for the calculation part to avoid running into strange behaviour in case your version of shell can't handle arithmetics on numerical as high as those returned by date +%s ...
If your version of at doesn't allow "now + XX second", then you can :
compute the number of seconds the script ran for
compute how many seconds to sleep ( sleep N ) to reach the next minute
and then : echo /path/to/script | at now + X minute
Is it possible to have a cronjob run every 15 minutes (over every hour etc..) except for at 3AM?
I have another special cronjob I want to run at 3AM, but I don't want the other one to run at the same time...
With one cron line, no. With three, yes:
# Every 15 minutes except for 3:00-3:59
*/15 0-2,4-23 * * * thejob
# 3:15, 3:30, 3:45
15-45/15 3 * * * thejob
# 3:00 dead
0 3 * * * otherjob
I made my own solution, but I wanted to see what other people thought of!
I put this on the top of my desired script. I wanted it to not run at the half hour either so it doesn't do it on both.
On top of the script:
if [ $(date +%M) = 00 ] || [ $(date +%M) = 30 ]
then
exit
fi
The cron line:
*/15 * * * * ~/path/to/file
Hope anyone uses my solution too.
0,15,30,45 0,1,2,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23 * * * your cron job
How can I set cron to run certain commands every one and a half hours?
That's not possible with a single expression in normal cron.
The best you could do without modifying the code is:
0 0,3,6,9,12,15,18,21 * * * [cmd]
30 1,4,7,10,13,16,19,22 * * * [cmd]
These might be compressible, depending on the version of cron you have to:
0 */3 * * * [cmd]
30 1-23/3 * * * [cmd]
Is there a good reason why you can't use 1 hour or 2 hours? It would be simpler for sure.
I haven't tried this personally, but you can find some info here on getting cron to run every 90 minutes: http://keithdevens.com/weblog/archive/2004/May/05/cron
An excert from the above link:
0 0,3,6,9,12,15,18,21 * * * <commands>
30 1,4,7,10,13,16,19,22 * * * <commands>
Two lines in the crontab. Along the lines of:
0 0,3,6,9,12,15,18,21 * * * /usr/bin/foo
30 1,4,7,10,13,16,19,22 * * * /usr/bin/foo
You could do it with two crontab entries. Each runs every three hours and they are offset by 90 minutes something like this:
0 0,3,6,9,12,15,18,21 * * *
30 1,4,7,10,13,16,19,22 * * *
*/10 * * * * root perl -e 'exit(time()%(90*60)>60)' && command
90 — it is one and a half hour in minutes
"> 60" — I give to cron ability to delay the start of script during a minute
Also with help of this hack you can set any period with a minute resolution
For example start the script every 71 minutes
* * * * * root perl -e 'exit(time()%(71*60)>60)' && command
You can achieve any frequency if you count the minutes(, hours, days, or weeks) since Epoch, add a condition to the top of your script, and set the script to run every minute on your crontab:
#!/bin/bash
minutesSinceEpoch=$(($(date +'%s / 60')))
# every 90 minutes (one and a half hours)
if [[ $(($minutesSinceEpoch % 90)) -ne 0 ]]; then
exit 0
fi
date(1) returns current date, we format it as seconds since Epoch (%s) and then we do basic maths:
# .---------------------- bash command substitution
# |.--------------------- bash arithmetic expansion
# || .------------------- bash command substitution
# || | .---------------- date command
# || | | .------------ FORMAT argument
# || | | | .----- formula to calculate minutes/hours/days/etc is included into the format string passed to date command
# || | | | |
# ** * * * *
$(($(date +'%s / 60')))
# * * ---------------
# | | |
# | | ·----------- date should result in something like "1438390397 / 60"
# | ·-------------------- it gets evaluated as an expression. (the maths)
# ·---------------------- and we can store it
And you may use this approach with hourly, daily, or monthly cron jobs:
#!/bin/bash
# We can get the
minutes=$(($(date +'%s / 60')))
hours=$(($(date +'%s / 60 / 60')))
days=$(($(date +'%s / 60 / 60 / 24')))
weeks=$(($(date +'%s / 60 / 60 / 24 / 7')))
# or even
moons=$(($(date +'%s / 60 / 60 / 24 / 656')))
# passed since Epoch and define a frequency
# let's say, every 7 hours
if [[ $(($hours % 7)) -ne 0 ]]; then
exit 0
fi
# and your actual script starts here
You could also use fcron which also accepts more complex time specifications such as :
# 01h30 my_cmd
#! /bin/sh
# Minute Cron
# Usage: cron-min start
# Copyright 2014 by Marc Perkel
# docs at http://wiki.junkemailfilter.com/index.php/How_to_run_a_Linux_script_every_few_seconds_under_cron"
# Free to use with attribution
# Run this script under Cron once a minute
basedir=/etc/cron-min
if [ $# -gt 0 ]
then
echo
echo "cron-min by Marc Perkel"
echo
echo "This program is used to run all programs in a directory in parallel every X minutes."
echo
echo "Usage: cron-min"
echo
echo "The scheduling is done by creating directories with the number of minutes as part of the"
echo "directory name. The minutes do not have to evenly divide into 60 or be less than 60."
echo
echo "Examples:"
echo " /etc/cron-min/1 # Executes everything in that directory every 1 minute"
echo " /etc/cron-min/5 # Executes everything in that directory every 5 minutes"
echo " /etc/cron-min/13 # Executes everything in that directory every 13 minutes"
echo " /etc/cron-min/90 # Executes everything in that directory every 90 minutes"
echo
exit
fi
for dir in $basedir/* ; do
minutes=${dir##*/}
if [ $(( ($(date +%s) / 60) % $minutes )) -eq 0 ]
then
for program in $basedir/$minutes/* ; do
if [ -x $program ]
then
$program &> /dev/null &
fi
done
fi
done
use "at" on crontab
the command is executed at midnight and then set to execute at 1.30
etc ..
0 */3 * * * echo "Command" | at now +90 minutes && Command
added the following to my crontab and is working
15 */1 * * * root /usr/bin/some_script.sh >> /tmp/something.log