I'm trying to schedule my first cron job:
* 0830 * * 1,3,5,0 ls -l
I'm expecting the job to run Mon, Wed, Fri, and Sun at 8:30am
It's
30 8 * * 0,1,3,5 ls -l
First the minutes, then hours; allways seperated by a whitespace
Related
I would like to run the cron job every 20 minutes between 9 AM and 11 PM and once an hour after 11 PM until 9 AM.
cron job settings
I created 2 cron jobs for the same script to achieve my goal. Did I do it correctly?
Thank you.
Not really. There are two issues:
you run the script also on 23:20 and 23:40
you run the script twice from 09:00 till 23:00 every hour.
The way to do it is:
*/20 9-22 * * * command
0 0-8,23 * * * command
You can validate this using crontab guru
System Date:
Wed Nov 22 02:14:54 UTC 2017
CronJob (save environment variables to file in /tmp)
02 12 * * * env > /tmp/env.txt
This job did not execute between at 02:12:00 - 02:13:00 despite being initialized at 02:10:00
The command env > /tmp/env.txt executes just fine when I do it outside of crontab. Can anyone tell me what I'm doing wrong?
You've reversed hours and minutes in your crontab file.
This should fix your problem:
12 02 * * * env > /tmp/env.txt
I'd like to run a bash command every 9th minute and every 70th minute.
man -S 5 crontab says:
Steps are also permitted after an asterisk, so if you want to say "every two hours", just use "*/2".
I ran the command
echo "Cron-job runs. ($(date))" >> crontest.log
with the cron expression
*/9 * * * *
which gave me
Cron-job runs. (We 25. Mar 13:27:01 CET 2015)
Cron-job runs. (We 25. Mar 13:36:01 CET 2015)
Cron-job runs. (We 25. Mar 13:45:01 CET 2015)
Cron-job runs. (We 25. Mar 13:54:01 CET 2015)
Cron-job runs. (We 25. Mar 14:00:01 CET 2015)
Cron-job runs. (We 25. Mar 14:09:01 CET 2015)
Cron-job runs. (We 25. Mar 14:18:01 CET 2015)
It seems, that */9 means "every minute that can be divided by nine without remainder" (this includes zero!) instead of "every ninth minute".
Are there cron-expressions to define intervals?
No, there is no facility for this specific use case. You could create a complex crontab which lists all the combinations;
0-54/9 0-21/3 * * * crontest
3-57/9 1-22/3 * * * crontest
6-51/9 2-23/3 * * * crontest
(This complex syntax is an extension, but since you were asking about */9 which is a similar extension, you should be able to use the above as well. See an earlier version of this answer for the full-hand syntax, which however I incorrectly identified as extended in my original answer.)
For execution every 70 minutes, a similar table would be a lot more complex, because 70 is not evenly divisible by 1440 (24*60). You end up with a periodicity over multiple days, so the table gets so complex as to beg for alternative solutions.
... One of which would be to use a self-scheduling at job:
#!/bin/sh
echo "$0" "$#" | at now + 70 minutes
:
# the rest of your crontest script here
You need to start this one manually the first time, but it will keep scheduling new jobs after that. (If your server is down for an extended period of time, you may need to restart it; but the job should survive the occasional quick reboot just fine.)
Or you could run your script every minute, and the script can check if it's the right time to run.
untested
#!/bin/bash
minute_of_the_epoch=$(( $(date +%s) / 60 ))
(( minute_of_the_epoch % 9 != 0 )) && exit
# rest of script ...
I am not sure how to run a cron job at 3 specific hours every day. I want to run it at 1pm, 2 pm and 3pm.
Is it possible, using a single expression?
you may use this:
# m h dom mon dow command
0 13,14,15 * * * /home/user/command
your /home/user/command will be run at 13:00, 14:00 and 15:00
As lenik stated, it can be done in single expression.
0 13,14,15 * * * <your-script-to-run>
Check this geedkstuff link for more examples
While the given answers are correct, an unexperienced user might not know where to put this expression. You have to edit the crontab file, like:
crontab -e
There you add
0 13,14,15 * * * /home/user/command
to execute your command at 13:00, 14:00 and 15:00. Also note that user has to be substituted with the user account the command is executed in.
You can try the following as well:
0 13-15 * * * /home/apps/sample.sh
To anyone landing here --> useful tool:
https://crontab.guru/
Please prefer range+step over commas:
Example: Run every 2h from 9h to 16h
m h dom mon dow command
0 9-16/2 * * * /home/user/command
Also applicable to minutes:
m h dom mon dow command
10-30/10 9-16/2 * * * /home/user/command
Crontab guru shows what it means, and the next scheduled jobs.
For example I typed this cron at 10h05:
I know that I can have something run every five minutes in cron with a line like:
*/5 * * * * /my/script
What if I don't want it running at 12:00, 12:05, 12:10, but rather at 12:01, 12:06, 12:11, etc? I guess I can do this:
1,6,11,16,21,26,31,36,41,46,51,56 * * * * /my/script
...but that's ugly. Is there a more elegant way to do it?
1-56/5 * * * * /my/script
This should work on vixiecron, I'm not sure about other implementations.
Use your first schedule:
*/5 * * * * /my/script
And add this to the start of your script:
sleep 60
(Yes, this is a joke)
This is quite an old topic, however as so much time has passed there are a few other options now. One of which is not to use cron at all, and use systemd timers. Using these gives you a higher granularity than seconds along with lots of other options
More information is available here https://wiki.archlinux.org/index.php/Systemd/Timers
eg to run a adhoc command
# systemd-run --on-calendar="*:1/5" /bin/touch /tmp/foo2
Running timer as unit run-r31335c4878f24f90b02c8ebed319ca60.timer.
Will run service as unit run-r31335c4878f24f90b02c8ebed319ca60.service.
# systemctl status run-r31335c4878f24f90b02c8ebed319ca60.timer
● run-r31335c4878f24f90b02c8ebed319ca60.timer - /bin/touch /tmp/foo2
Loaded: loaded
Transient: yes
Drop-In: /run/systemd/system/run-r31335c4878f24f90b02c8ebed319ca60.timer.d
└─50-Description.conf, 50-OnCalendar.conf, 50-RemainAfterElapse.conf
Active: active (waiting) since Wed 2017-10-25 09:05:13 UTC; 40s ago
# ls -l /tmp/foo*
-rw-r--r-- 1 root root 0 Oct 25 09:06 /tmp/foo2
# sleep 300; ls -l /tmp/foo*
-rw-r--r-- 1 root root 0 Oct 25 09:11 /tmp/foo2
# date; ls -l /tmp/foo2
Wed Oct 25 09:21:42 UTC 2017
-rw-r--r-- 1 root root 0 Oct 25 09:21 /tmp/foo2
edit: these type of timers wont persist over reboot, if you want them to make sure you generate a proper service file, with the relevant oncalendar line
I'd create a new script "delaystart" that takes a sleeping period as first parameter and the script to run as the rest. I'd make the script check the crontab line for the line with the script and only start the script if the line is not commented out. That makes it reusable, and ps won't report the script as running when it really isn't.
#!/bin/bash
sleeptime=$1
sleep ${sleeptime}
shift
if ( ! crontab -l | grep -e '#.+delaystart '${sleeptime} $* ) then
$*
fi
sean.bright's joke got me thinking... why not use...
* * * * * /my/script
...and within the script do this...
#!/bin/bash
export WHEN=`date '+%M'`
echo $WHEN
export DOIT=`echo "$WHEN % 5" | bc`
echo $DOIT
if [ $DOIT != 0 ] ; then
echo "ha ha ha"
fi
echo "done"
...a kludge... maybe, but as ugly as the crontab... I don't know.