Run script only once a day

I have a script that backs up files.

But I only want to run it once a day.

I did a search but found only answer involving cron.

I would prefer not to run it as a cron job.

The script is rather long. Not sure if you want me to post it.

Would appreciate some help or point me somewhere.

Hello,

Can I ask why you would prefer not to run it via a cron job ? This is absolutely the standard way to schedule jobs on a UNIX-style system, and is the method I'd go with myself if I wanted to set a script to run every day.

I appreciate your response.

There are multiple ways of doing things.

I am open to both the cron way and other ways.

I have this.

cd /media/storagedrive/Ubuntu_Mate_18.04/
touch $( date '+%m-%d-%Y_%I:%M-%p' )

I need help checking that file for the date and exiting if it is today's date.

Thanks.

Hello,

One approach there would be to assign today's date to a variable (assuming you are on a Linux system, or some other system which uses the GNU coreutils date command), and then use that string for your file check.

So something like:

#!/bin/bash

today=`/bin/date -d today '+%m-%d-%Y_%I:%M-%p'`

if [ -f /media/storagedrive/Ubuntu_Mate_18.04/$today ]
then
   echo It exists
else
   echo It does not exist
fi

would do the trick, off the top of my head.

I do not understand how it works.

What is it checking for?

I will study it some more.

Hello,

Here, the script breaks down as follows:

  1. We run the command /bin/date -d today '+%m-%d-%Y_%I:%M-%p', and assign the output of that command to the variable $today.
  2. If a file exists in the directory /media/storagedrive/Ubuntu_Mate_18.04/ with the same name as the contents of the variable $today, then we print the message "It exists"; otherwise if no such file can be found, we print the message "It does not exist".

That's pretty much all there is to this one. So we use the -f conditional test to check if a file with the desired name exists, and then branch our script's logic according to whether such a file can be found or not.

It might be easier to understand if I demonstrate an interactive session (using the current working directory only, since of course /media/storagedrive/Ubuntu_Mate_18.04/ does not exist on my test system:

$ ls -l
total 4
-rwx------ 1 unixforum unixforum 137 Aug 27 17:51 script.sh
$ bash -x ./script.sh 
++ /bin/date -d today +%m-%d-%Y_%I:%M-%p
+ today=08-27-2022_09:09-PM
+ '[' -f 08-27-2022_09:09-PM ']'
+ echo It does not exist
It does not exist
$ today=`/bin/date -d today +%m-%d-%Y_%I:%M-%p`
$ echo $today
08-27-2022_09:09-PM
$ touch $today
$ ls -l
total 4
-rw-rw-r-- 1 unixforum unixforum   0 Aug 27 21:09 08-27-2022_09:09-PM
-rwx------ 1 unixforum unixforum 137 Aug 27 17:51 script.sh
$ bash -x ./script.sh 
++ /bin/date -d today +%m-%d-%Y_%I:%M-%p
+ today=08-27-2022_09:09-PM
+ '[' -f 08-27-2022_09:09-PM ']'
+ echo It exists
It exists
$ 

Hope this helps !

Thanks for your patience.

I ran that code.

andy@7 /media/storagedrive/Ubuntu_Mate_18.04> ls
08_20_22_Better_Boy_Tomato.zip
08-27-2022_03:35-PM

But it does not detect the time_date file?

Hello,

Do the time and date being assigned to the $today variable exactly match the filename of the file you want to check for ? If the file was created at a different time of day or on a different date from the precise time the script was run, then there will of course be a difference between what the script looks for and what is on disk.

You had mentioned in your first reply that you wanted code to check for the existence of a particular file that you had created via the touch command. What I've shown you here is the general principle of how to do that. But you'll need to ensure that you adapt that principle to match your own local circumstances, so you can actually detect the file that does in fact exist (when it does exist, naturally).

This seems to check that the script ran in a specific minute, and so can be run again 60 seconds later ? date '+%F' would be necessary and sufficient.

It also seems to omit the actual touch command, and to leave a trail of date files where it ran (which may or not be useful for audit purposes).

I think I would prefer a file with a unique name, containing the stamp for the latest execution. The actual time of that run would show up in ls -l if needed.

I see. The file I created was on the same date but different time.

I put this in my cron. Is this ok?

# Run file backup once a day (Not needed in startup programs.)
00 11 * * * /home/andy/bin/Backup_18_04.sh

Would putting the script in cron.daily work?

That looks fine -- runs every day of the year at 11:00 on your local time zone.

I believe cron.daily would work, but.

The time of "daily" is set in another cron file, /etc/crontab.

The lines look quite similar to cron entries: this is my relevant /etc/crontab entry:

25 6 * * *  root  test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )

It looks like cron would run all the daily scripts at 06:25, but not if anacron is installed and executable.

Traditionally, Linux servers are on 24/7, and cron jobs run to time: if the system is off, they just do not get run. anacron is an additional feature which is designed for personal and laptop systems, which may be turned off at any time, maybe for several days.

My /etc/anacrontab file contains lines like this:

1 5 cron.daily  run-parts --report /etc/cron.daily

In anacron, the numbers mean something very different. The 1 is the period: it means "attempt to run this command every day, but only once per day". The 5 means "delay for 5 minutes before running". So if your system is running at midnight, anacron will run the scripts in cron.daily at 00:05, but if you only boot your Laptop for the first time today at 14:32, the scripts get run at 14:37.

run-parts is a script that runs all the scripts in /etc/cron.daily in sorted order (ASCII), so you can choose names that prioritise them as you wish. Only one of them will be running at any time.

OK, I have an anacron system on Linux Mint 19.3, because this file passes the test -x:

$ ls -l /usr/sbin/anacron
-rwxr-xr-x 1 root root 34832 May 29  2017 /usr/sbin/anacron

Personally, I would think that the daily, weekly and monthly files are easy to forget about, and are best used for system tasks only. I prefer to give each cron entry a specific time, and keep everything in the standard user crontabs.

Thanks.

That looks fine -- runs every day of the year at 11:00 on your local time zone.

Would it still run if my computer is not on at 11:00?

This finds the correct string.

Aug 27 11:25:45 7 dbus-daemon[857]: [system] Activating via systemd: service name='org.freedesktop.hostname1' unit='dbus-org.freedesktop.hostname1.service' requested by ':1.163' (uid=1000 pid=5177 comm="geany /home/andy/bin/Backup_18_04.sh " label="unconfined")

grep 'Backup_18_04.sh' /var/log/syslog > temp.txt
geany temp.txt
rm temp.txt

Does syslog log whenever any script is run?

crond (the cron daemon) only runs jobs at the moment when their time spec occurs. It will never go retrospectively. In particular, for e.g. an hourly spec, how many previous hours would you want? The only exception to that is the @reboot timespec.

In the plain cron case, for your job scheduled for 11:00, if you turned on your system at 11:02 it would not run until 11:00 tomorrow (and not then either if it was off at that time tomorrow too). That is the issue that anacron is designed to fix.

I can only see messages about cron and anacron themselves on /var/log/syslog. There is no logging of jobs run, although this may be configurable. In any case, it would not it a good idea to flood the syslog with cron messages. I do not even use my Linux mail, so I always wrap my cron jobs within a redirect of both stdout and stderr, and log them in userspace where I will expect to find them.

This is a good reference.

https://linux.die.net/man/8/anacron

Anacron just fills in the gaps where the system was not running. It still does nothing retrospectively. It merely runs hourly, daily, weekly and monthly jobs that are overdue as soon as it notices them (whereas cron would run them only at the next specified time, at which point your system may again not be switched on).

I don't know what would happen if both anacron and cron were configured to run the same weekly or monthly job. My crontab seems to inhibit cron entries if they are also executable by anacron, which seems to be a manual (i.e. clumsy and error-prone) mechanism.

Thanks.

Aug 28 05:21:29 7 CRON[938]: (andy) CMD (/home/andy/bin/Backup_18_04.sh)

On Linux with systemd, the systemd wants to replace ("absorbe", "assimilate") the cron services.
You can use it already now.

man systemd.timer

https://opensource.com/article/20/7/systemd-timers
Persistent=true lets it behave like anachron.

Use systemd timers instead of cronjobs

I looked at using systemd timers.

It is a boatload of work compared to using cron.

:slight_smile: