Cron jobs -- to run every 5 seconds - cron

I want to create cron job that runs a script every 5 seconds. Seeing that cron jobs only allows increments of minutes 0-59 and so on.
I thought to create another script that calls my original script written below.
#!/bin/bash
while true
do
# script in the same directory as this script. is this correct?
bash makemehappy.sh
sleep 1
done
I now, need to know how to run this script every time i boot my computer and for it to start itself if it isn't running for some reason.
I am also aware that running this script every minute wouldn't be a good thing. :)
if there is an easier way to run a script every 5 seconds please advise.
Please and thank you.

I wouldn't use cron for this. I would use that bash script (use an absolute path, unless you want it to be portable and know that the directory structure will be preserved).
Instead, I would just sleep 5, just like you did (only 5 seconds instead of 1).
As far as starting it with your system, that depends on the system. On (some) Linux distros, there's a file called /etc/rc.local in which you can add scripts to run when the system starts. Well... I shouldn't be so general, the distros that I have used have this. If you're running Ubuntu, there is no longer an inittab, they use upstart, btw.
So if you have an endless loop and an entry in /etc/rc.local, then you should be golden for it to run endlessly (or until it encounters a problem and exits).

Try using anacron or, better yet, an init script to start when the computer starts.
If you want the script to "restart itself", you'll need to run something every few minutes to check the original is still running. This can be done in inittab (/etc/inittab) or, on Ubuntu, /etc/event.d. Try man 5 inittab, looking at the 'respawn' option.

Some crons have an #reboot time specifier (this covers all the time and date fields). If yours does, you can use that. If this is a "system" service (rather than something running for yourself), the other solutions here are probably better.

Init scripts are fine at boot, but don't detect if a process fails and has to be restarted. supervisord does a great job of detecting failed processes and restarting them. I'd recommend a script with a 5-second loop like #Tim described, but wrap supervisord around it to make sure it keeps running.

As explained in detail in my answer to a similar question, you can use SystemD timer units with whatever schedule that you want - down to a theoretical 1 nanosecond schedule with no sleep kludges
Quick overview:
Setup a SystemD service to run what you want - this can be as simple as:
/home/myusuf3/.config/systemd/user/makemehappy.service
[Unit]
Description=Make me happy
[Service]
ExecStart=/home/myusuf3/.local/bin/makemehappy.sh
Setup a SystemD timer with the schedule that you want, as documented in man systemd.timer:
/home/myusuf3/.config/systemd/user/makemehappy.timer
[Unit]
Description=Schedule to make me happy
[Timer]
OnBootSec=5
OnUnitActiveSec=5
AccuracySec=1
Enable and start the timer:
:
systemctl --user daemon-reload
systemctl --user enable makemehappy.timer
systemctl --user start makemehappy.timer
(after you enable it, it will autostart every time you start the computer, but you probably want to start it now anyway).

To answer the question in the title, this is how to run a cronjob every 5 seconds :
* * * * * /path/to/script.sh
* * * * * sleep 5 && /path/to/script.sh
* * * * * sleep 10 && /path/to/script.sh
* * * * * sleep 15 && /path/to/script.sh
* * * * * sleep 20 && /path/to/script.sh
* * * * * sleep 25 && /path/to/script.sh
* * * * * sleep 30 && /path/to/script.sh
* * * * * sleep 35 && /path/to/script.sh
* * * * * sleep 40 && /path/to/script.sh
* * * * * sleep 45 && /path/to/script.sh
* * * * * sleep 50 && /path/to/script.sh
* * * * * sleep 55 && /path/to/script.sh
It's not beautiful, but this solution comes with no extra tools nor dependencies. So if you have working cron jobs, this should work right away.

Related

Docker cron scheduled job not running

I am trying to use a docker container based on an Alpine image to run a scheduled cron job, following this tutorial, but after printing the statement in my startup script, the container just exits, without running my other script.
My docker-compose service is configured as follows:
cron:
image: alpine:3.11
command: /usr/local/startup.sh && crond -f -l 8
volumes:
- ./cron_tasks_folder/1min:/etc/periodic/1min/:ro
- ./cron_tasks_folder/15min:/etc/periodic/15min/:ro
- ./cron_tasks_folder/hourly:/etc/periodic/hourly/:ro
- ./scripts/startup.sh:/usr/local/startup.sh:ro
So it runs an initial script called startup.sh and then starts the cron daemon. The startup.sh script contains the following:
#!/bin/sh
echo "Starting startup.sh.."
echo "* * * * * run-parts /etc/periodic/1min" >> /etc/crontabs/root
crontab -l
sleep 300
I dropped a sleep command in there just so I could launch an interactive shell on the container and make sure everything inside it looks good. The script creates another folder for 1min scripts. I have added a test script in there, and I can verify it's there:
/etc/periodic/1min # ls -a
. .. testScript
The script is executable:
/etc/periodic/1min # ls -l testScript
-rwxr-xr-x 1 root root 31 Jul 30 01:51 testScript
And testScript is just an echo statement to make sure it's working first:
echo "The donkey is in charge"
And looking at the root file in etc/crontabs, I see the following (I've re-run the container several times, and each time it's creating a new 1min folder, which is unnecessary, but I think not the problem here):
# do daily/weekly/monthly maintenance
# min hour day month weekday command
*/15 * * * * run-parts /etc/periodic/15min
0 * * * * run-parts /etc/periodic/hourly
0 2 * * * run-parts /etc/periodic/daily
0 3 * * 6 run-parts /etc/periodic/weekly
0 5 1 * * run-parts /etc/periodic/monthly
* * * * * run-parts /etc/periodic/1min
* * * * * run-parts /etc/periodic/1min
* * * * * run-parts /etc/periodic/1min
* * * * * run-parts /etc/periodic/1min
* * * * * run-parts /etc/periodic/1min
The echo statement in testScript is never printed to my terminal, and the container exits with exit code 0 shortly after starting. I want to print this statement every minute... what am I missing?
In the docker compose file you have
command: /usr/local/startup.sh && crond -f -l 8
The intention is to run as a shell command, but it's not at all clear from the question that's what's going to happen; that depends on your ENTRYPOINT. Since it's defined with [] brackets, not additional shell will be provided. The command value will be passed as arguments to the ENTRYPOINT.
Assuming that will become a shell command, && in the shell runs the left hand side, and if that succeeds, then runs the right hand side. So startup.sh needs to complete before crond is executed. startup.sh ends with
sleep 300
crond is invoked only after that 300 seconds.
In either case, crond is either not invoked at all, or sleep has not been completing. The comments show that an error starting crond was discovered.
Using an entrypoint such as this is standard practice to configure the environment before, or provide runtime parameters when, invoking the main executable. To do it right, you should make sure to use exec to run the main executable so that it receives the signals that would otherwise go to the bash shell running the entrypoint script.
So at the end of startup.sh:
exec crond -f -l 8
Will replace the shell running startup.sh with crond, so that crond receives all signals (at this point the shell is gone). It's subtle but important!
In general, keep the invocation of the application as simple as possible. Case in point, your execution process was split between entrypoint, command, and startup script, with no clear interface between them. You wouldn't have gotten hung up on the invocation if you had put crond directly into the Dockerfile and left it at that. Sometimes arguments must be provided at runtime, but environment variables - which have names, not just positions - are often preferred. This keeps invocations simple and debugging straightforward. But, when that doesn't work, a shell script entrypoint is a great solution - just make sure to exec your final process!

Crontab every 5 minutes, but not on 5,10,15, etc

Some of my sites need regular crontabs, I use this to start a cronjob every 5 minutes "*/5 * * * *".
The crontabs are small, light, but there are starting to be several sites that need them, and starting them all together, it starts not being a very good idea.
With this "*/5" the cron starts at 5, 10, 15 20, etc... is it possible to make it start at, for example 8,13,18,23, etc?
Vixie cron accepts steps in a range (thanks Keith Thompson), so you can do
3-58/5 * * * * my_command
With other versions of cron, this may not be supported and you'd just have to do
3,8,13,18,23,28,33,38,43,48,53,58 * * * * my_command
Another option is something like
*/5 * * * * sleep 3m ; my_command
This could be adapted to sleep for a random time, thus further spreading out the jobs. For instance, you could do
*/5 * * * * /bin/bash -c 'sleep $((RANDOM/(32767/180))) ; my_command'
or use SHELL = /bin/bash further up in your crontab to make the /bin/bash -c unnecessary, if you're okay with using bash to run all the other cron jobs following the SHELL = line. $RANDOM in bash expands to a random integer between 0 and 32767, so this gets you a delay of up to 180 seconds.

How to reboot via cron on scheduled basis. Ubuntu 14.04

I have a very simple script that works from the command line.
#!/bin/bash
reboot
When I put a call to execute the script into root users crontab -e using the following format it does not run. It does run the first two commands, just that last one is giving me grief. I have no MTA installed as I do not need it.
*/10 * * * * service jwtpay restart
0 3 * * * bash /root/backup/mongo.backup.s3.sh kickass /root/backup >/dev/null 2>&1
0 */3 * * * bash /root/reboot.sh >/dev/null 2>&1
What am I missing?
Maybe the script is not executable... Since you use root's crontab why call the binary via a script and not the binary itself? Use the full path to the binary. It may vary on your system. Find out where it is with which reboot.
0 */3 * * * /sbin/reboot
Don't forget to restart the cron daemon, after changeing the crontab.

Can't make crontab work

I am new to Linux and Ubuntu and I seldom have to use it. I am trying to make this PHP script to run every minute using cron, but firstly I wanted to make some tests.
I created an empty file at /var/www/html/ called test. I ran on terminal:
sudo crontab -e
And added this line:
0 * * * * rm /var/www/html/test
Then saved it and exited. It said "Installing new Crontab"
Nothing happened. Then I created a file bfile.sh that contained:
#!/bin/sh
rm /var/www/html/test
and added the following to crontab:
0 * * * * bash /var/www/html/bfile.sh
Still nothing happened.
What do I have to do to see anything happening from crontab? By the way I checked and the service is running
0 * * * * basically says "run this at 0th minute of every hour."
If you need cron to run your command every minute do * * * * *.
0 * * * * runs once every 1 hour. If you want to run every minute it should be */1 * * * *
You can also check the /var/log/cron file for any errors

Using Cron to Reboot

I'm using a Raspberry Pi for a status display, but for whatever reason it gets incredabbly sluggish after a day or so of running so I wanted to reboot it every day so I setup a cron job to do that every morning at 8:50. But, it doesn't seem to be working. Is there anything special about using cron to do a reboot?
This is my crontab for the root user:
# m h dom mon dow command
50 8 * * * shutdown now -r >> /var/log/cron.log
0,30 * * * * date >> /var/log/cron.log
The second line works just fine, but I can't seem to get the restart command to work. It doesn't even output anything to the log.
Try using the fully specified path to shutdown. date may be in the PATH in roots cron environment, /sbin may not be looked up.
You need to edit the root user crontab
sudo crontab -e
then..
50 8 * * * reboot
Save and exit.

Resources