This would, however, fail if the computer is off at 23:00, and is started, say, at 23:05, would require complex process management with bash, would require waking up every minute, and maybe requiring lock files too, so is generally an error-prone way.
To avoid this problem use anacron
instead of cron
My distribution uses anacron
to ensure that the daily tasks are only run once per day (Ubuntu 20.04)
Looking at the configurations files (and only looking at daily tasks)
/etc/crontab
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
This is a failsafe entry (when anacron is not installed), run the daily scripts at 06:25 , but as you correctly mentioned the system must be switched on at 06:25 for this to work.
When anacron
is installed, look at the next configuration file.
/etc/anacrontab
# /etc/anacrontab: configuration file for anacron
# See anacron(8) and anacrontab(5) for details.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
HOME=/root
LOGNAME=root
# These replace cron's entries
# Frequency (in days) Delay JobId Command
1 5 cron.daily run-parts --report /etc/cron.daily
Daily, 5 mins after starting anacron
, run the scripts in /etc/cron.daily. So, if I switch my laptop on at 10:00 and again at 15:00 the daily scripts are only run once, 5 mins after starting anacron
at 10:00
Ubuntu uses systemd
instead of init
. So the following config files are relevant to understand how anacron
is started.
/lib/systemd/system/anacron.service
[Unit]
Description=Run anacron jobs
After=time-sync.target
# By default, anacron will not run when no AC power is connected to system.
# If you are using systemd and want to run anacron even when running on
# battery, you should create the following file with the specified content
# and then call "systemctl daemon-reload":
# /etc/systemd/system/anacron.service.d/on-ac.conf:
# [Unit]
# ConditionACPower=
# See /usr/share/doc/anacron/README.Debian for detailed information.
ConditionACPower=true
Documentation=man:anacron man:anacrontab
[Service]
EnvironmentFile=/etc/default/anacron
ExecStart=/usr/sbin/anacron -d -q $ANACRON_ARGS
IgnoreSIGPIPE=false
KillMode=mixed
# Use SIGUSR1 to stop gracefully
KillSignal=SIGUSR1
[Install]
WantedBy=multi-user.target
And finally /lib/systemd/system/anacron.timer
[Unit]
Description=Trigger anacron every hour
[Timer]
OnCalendar=*-*-* 07..23:30
RandomizedDelaySec=5m
Persistent=true
[Install]
WantedBy=timers.target
It takes a bit of mental agility to get your head around, and I do like @Romeo Ninov's solution for it's simplicity. The downside is something starting every 5 mins to check and exit, which affects it's scalability.
However I did implement a daily backup solution for my laptop (not switched on every day) an it worked very well, it also allowed me to switch on for a short time before it kicked in (I made the delay more that 5 mins) so I could check my email quickly without triggering a potential new backup.
You can specify your own config file anacron -t <configfile>
, if you want to avoid tampering with the system configuration file.
For more information:
man anacron
man anacrontab