How to test command anacron? - linux

uname -r
4.5.5-300.fc24.x86_64
I have appended 0 0 test touch ~/ana.cron to /etc/anacrontab. But there is no effect after rebooting or resuming from sleep or running sudo anacron -f. I can't find the output file ana.cron.
cat /etc/anacrontab
# /etc/anacrontab: configuration file for anacron
# See anacron(8) and anacrontab(5) for details.
SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# the maximal random delay added to the base delay of the jobs
RANDOM_DELAY=45
# the jobs will be started during the following hours only
START_HOURS_RANGE=3-22
#period in days delay in minutes job-identifier command
1 5 cron.daily nice run-parts /etc/cron.daily
7 25 cron.weekly nice run-parts /etc/cron.weekly
#monthly 45 cron.monthly nice run-parts /etc/cron.monthly
0 0 test touch ~/ana.cron
How to solve this?

I'm not sure period can be of 0.
1 0 test.daily nice run-parts touch ~/ana.cron
If you want your task to be run at startup, then use #reboot
#reboot test.reboot nice run-parts touch ~/ana.cron

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!

Trigger a bash script at startup to execute periodically

I have made a bash script, let's call it script.sh, which has the next sctructure:
#!/bin/bash
while true
do
do_something()
sleep 1800 #seconds
done
I want the script to run as a task at startup although there is no user connected to the system. I thought that I could use 'nohup script.sh' but I don't know if I can use it at startup without any user connected. Have anybody some idea?
Look into using /etc/cron.hourly/ for an hourly script. It will run hourly at some interval past the hour. On RHEL, this is defined in /etc/cron.d/0hourly as 1 minute past the hour.
You could then extend this framework for half-hour intervals (1800s = 30 minutes), e.g., in /etc/cron.d/1_halfhourly:
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
00,30 * * * * root run-parts /etc/cron.halfhourly
And put your script, or symlink it, in /etc/cron.halfhourly.
Naturally, this could be extended right down to one minute intervals, e.g., in /etc/cron.d/2perminute:
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
* * * * * root run-parts /etc/cron.perminute
This would run every script under /etc/cron.perminute each minute.

Cronjob cron.daily does not run (debian)

I got a script to run daily at any time. So /etc/cron.daily seems to be an easy solution.
But now I got the problem, the cronjob won't run that script. It seems like the cronjob won't run any of the daily jobs.
So I tried to put it to cron.hourly and everything worked fine.
But I dont want to run the backup script every hour.
/etc/init.d/cron start|stop works without errors.
/etc/crontab looks like default:
m h dom mon dow user command
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
As it won't run I tried to install anacron but without any changes.
Why does it run the hourly scripts but not the daily ones?
Many thanks to all of you!
It might be, that one of your daily-scripts is misbehaving. Try running them manually. I removed the logwatch package and the cron.daily job and it worked again.
This is my /etc/crontab
# /etc/crontab: system-wide crontab
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# m h dom mon dow user command
16 * * * * root cd / && run-parts --report /etc/cron.hourly
12 2 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
41 1 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
9 3 30 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#
try running the daily like so
run-parts -v --report /etc/cron.daily
you can also use --list or --test for more output. In my case I removed the misbehaving script and the daily job worked again
I had the same problem with one of my scripts in /etc/cron.daily
The name of the script was backupBugzilla.sh
After renaming the script to backupBugzilla it worked.
Do you have anacron installed?
# dpkg --get-selections | grep anacron
If yes, it doesn't runs the daily, weekly and monthly scripts.
the manpage of run-parts states:
If neither the --lsbsysinit option nor the --regex option is given then the names must consist entirely of ASCII upper- and lower-case letters, ASCII digits, ASCII underscores, and ASCII minus-hyphens.
I assume it does not like the name of your script. for example it does not like the extension ".sh" as a dot is not allowed.
I had this problem, and it was because the owner of my script in /etc/cron.daily was not root. Make root the owner of all the scripts in /etc/cron.daily:
sudo chown root /etc/cron.daily/*
Also, be sure the scripts are executable:
sudo chmod +x /etc/cron.daily/*
I have a wheezy not start the /etc/init.d/anacron.
My solution:
edit /etc/init.d/anacron
Required-Start: $all
save and run:
update-rc.d /etc/init.d/anacron defaults
now works well when wheezy start.

EC2 Micro Instance CPU spikes to 100% at regular interval every day

I know Amazon throttles micro instance if it uses up certain number of CPU time, but I don't think this is the case. All the spikes appear at around 6:30 to 6:40 UTC. I checked my cron job and there is nothing scheduled for that time:
#reboot ~/path/to/script1.sh >> ~/log/cron.log
0 13 * * * ~/path/to/script2.sh >> ~/log/cron.log
What else could it be?
PS: Notice the CPU Utilization dropdown is set at "Maximum". The graph looks similar for "Average".
PPS: This instance is part of a 2-instance load-balanced setup.
Here's what's inside my /etc/cron.daily (the other crons are empty):
apport, apt, aptitude, bsdmainutils, dpkg, logrotate, man-db, mlocate, passwd, popularity-contest, standard, update-notifier-common
Usually, Ubuntu AMIs on Amazon have their daily cron jobs under /etc/cron.daily scheduled for morning hours. This schedule is managed using /etc/crontab. Here's how a sample /etc/crontab looks like:
$ cat /etc/crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# m h dom mon dow user command
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#
Clearly, daily tasks run at 6:25am. You may want to tweak these settings to move daily tasks to some other time if this is impacting direct delivery of your server(s). Further, you could investigate items under /etc/cron.daily. For me, it looks like:
$ ls /etc/cron.daily/
apport apt aptitude bsdmainutils dpkg logrotate man-db mlocate popularity-contest standard
Out of these, typically man-db and logrotate may take up major CPU time for execution. These are standard tasks and can be tweaked for optimum performance. You may want to look into tuning your logrotate and man-db policies.
Hope this helps.

How do I make cron run something every "N"th minute, where n % 5 == 1?

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.

Resources