When you use Linux, it is often suggested that you make frequent backups of your system. Most users that follow this advice like to automate the task, and for reasons we will leave to others to explain, one suggested strategy is to use Back In Time to back up your home directory, and Timeshift to back up system files and settings. Both of these programs are readily available in the repositories of most Linux distros, and even come preinstalled in some distros. This article is not about installing or using either of these programs; there are many articles and videos on those topics.
Instead, this article deals with one particular and sometimes annoying quirk of Timeshift – it does not allow you to schedule backups at a particular time of day if you use its GUI to schedule backups (this assumes you are not doing hourly backups; in that case you probably want a backup to be made every hour no matter what). Maybe you are using Linux to run a home theater PC – in that case you probably don’t want Timeshift deciding to do a backup during prime time. Or in an office setting, you might not want Timeshift running during your busiest time of day. But Timeshift gives you no way to control that (unless you resort to running it from the Linux command line, and that may have certain other disadvantages). Wouldn’t it be nice to be able to force Timeshift to do its backups in the middle of the night, or at some other preferred time of day?
Well it turns out it is possible. In fact, a few suggestions were posted in Timeshift issue #64 and we found this comment by “MissingUser” particularly interesting:
Each snapshot has a file called info.json with information about the result of the copy.
This file contains copy information and a “created” field with the timestamp of the start of the copy.
This information is used by Timeshift to determine the next copy.
If the timestamp is changed to a timestamp with the time at which the copy would have been desired, the next and subsequent copies will be made at that time.
For example: a timestamp 1657555200 (a copy made at 16:00 hours) can be changed to 1657526400 with the same information but at 08:00 hours, which will cause copies to be made at 08:00 hours from now on.
The nice thing about this is it allows you to keep using the GUI. The bad thing is that nobody wants to recalculate timestamps by hand. So, with a little help from AI, we came up with a bash script that does it for you. This one works on weekly snapshots. We placed it in the /root directory (it must run as root) and made it executable. You can run sudo nano adjust-timeshift-weekly-backup-time.sh
and then copy and paste this code into the editor (of course you can use your favorite text editor if that’s something other than nano):
#!/bin/bash
# This is the script for weekly snapshots, adjusts time to be at 5 AM.
# Find the most recent directory in "/storage/location/of/timeshift/snapshots-weekly"
latest_dir=$(find "/storage/location/of/timeshift/snapshots-weekly" -mindepth 1 -maxdepth 1 \( -type d -o -type l \) -printf '%T@ %p\n' | sort -n | tail -1 | cut -d' ' -f2-)
# Get the path to the info.json file
info_json_file="$latest_dir/info.json"
# Get the current UNIX timestamp from the info.json file
current_timestamp=$(grep -o '"created" : "[^"]*' "$info_json_file" | cut -d'"' -f4)
# Convert the current timestamp to a human-readable date and time
current_date_time=$(date -d "@$current_timestamp" "+%Y-%m-%d %H:%M:%S")
# Check if the current timestamp is near 5 AM (within 5 minutes)
if [[ $(date -d "$current_date_time" "+%H%M") -lt 0505 || $(date -d "$current_date_time" "+%H%M") -gt 0500 ]]; then
# Calculate the new UNIX timestamp for 5 AM on the same day
new_timestamp=$(date -d "$(date -d "$current_date_time" "+%Y-%m-%d") 05:00:00" "+%s")
# Update the info.json file with the new timestamp
sed -i "s/\"created\" : \"$current_timestamp\"/\"created\" : \"$new_timestamp\"/" "$info_json_file"
fi
What this script does is look at the timestamp in the info.json file and if it is not within 5 minutes of 5 AM, it will change it to be set to 5 AM of the same day. This will cause Timeshift to schedule the next backup at 5 AM (in this case the following week). Near the top of the script you will see two places where it says “/storage/location/of/timeshift/snapshots-weekly” and in both places this must be changed to the actual path to the snapshots-weekly file. For example, it may be at something like /media/username/Backup Volume/timeshift/snapshots-weekly but you should be able to find it in the /timeshift directory on the drive you selected as the destination for backups – you can navigate to the snapshots-weekly directory and the use the Linux pwd command to show you the full path.
Obviously you can also change the time of day if you prefer some time other than 5 AM, if you find all the places in the script where it refers to that time and change them (but where the script shows “-lt 0505” make sure you don’t change that last “05”). Note that Timeshift only checks for backups once an hour so setting a time for, say, 4:30 AM will probably result in the next backup running at 5AM.
As noted above, we named the script adjust-timeshift-weekly-backup-time.sh and placed it in the /root directory, and then made certain it is owned by root and is executable:
sudo chown root:root /root/adjust-timeshift-weekly-backup-time.sh
sudo chmod 755 /root/adjust-timeshift-weekly-backup-time.sh
The final step is to make it run once a week to check that the previous weekly timestamp was at 5 AM (it could get changed if the computer was powered off at the time the backup was supposed to take place):
sudo crontab -e
When the crontab editor opens, insert this line:
@weekly /root/adjust-timeshift-weekly-backup-time.sh
Save the change and exit the editor.
Now maybe you want to also save some monthly backups. We noticed that Timeshift seems to want to do monthly backups two hours after it does the weekly backups, so we set those to run at 7 AM. The procedure is almost exactly the same, first we made a new script in the /root directory called adjust-timeshift-monthly-backup-time.sh (you can use sudo nano /root/adjust-timeshift-monthly-backup-time.sh
and copy and paste this script into the editor):
#!/bin/bash
# This is the script for monthly snapshots, adjusts time to be at 7 AM.
# Find the most recent directory in "/storage/location/of/timeshift/snapshots-monthly"
latest_dir=$(find "/storage/location/of/timeshift/snapshots-monthly" -mindepth 1 -maxdepth 1 \( -type d -o -type l \) -printf '%T@ %p\n' | sort -n | tail -1 | cut -d' ' -f2-)
# Get the path to the info.json file
info_json_file="$latest_dir/info.json"
# Get the current UNIX timestamp from the info.json file
current_timestamp=$(grep -o '"created" : "[^"]*' "$info_json_file" | cut -d'"' -f4)
# Convert the current timestamp to a human-readable date and time
current_date_time=$(date -d "@$current_timestamp" "+%Y-%m-%d %H:%M:%S")
# Check if the current timestamp is near 7 AM (within 5 minutes)
if [[ $(date -d "$current_date_time" "+%H%M") -lt 0705 || $(date -d "$current_date_time" "+%H%M") -gt 0700 ]]; then
# Calculate the new UNIX timestamp for 7 AM on the same day
new_timestamp=$(date -d "$(date -d "$current_date_time" "+%Y-%m-%d") 07:00:00" "+%s")
# Update the info.json file with the new timestamp
sed -i "s/\"created\" : \"$current_timestamp\"/\"created\" : \"$new_timestamp\"/" "$info_json_file"
fi
You would then correct the path “/storage/location/of/timeshift/snapshots-monthly” in both places it appears, as before, and then change the ownership and permissions as you did with the previous script:
sudo chown root:root /root/adjust-timeshift-monthly-backup-time.sh
sudo chmod 755 /root/adjust-timeshift-monthly-backup-time.sh
And then in the root crontab you would add this line:
@monthly /root/adjust-timeshift-monthly-backup-time.sh
If you make daily backups (we don’t – how often do you make changes to your system files anyway?), you could make a similar script for daily backups (probably one that runs a couple hours before the one for weekly backups, for example at 3 AM by making the appropriate changes. Hint: start with the monthly script and change all instances of 7 to 3, and then fix the paths so they point at the daily backups).
As we noted we used an online AI chat interface to help develop this but at this point in time it doesn’t yet just write perfectly working code for you. We had to check each line of code and in some cases found errors that had to be corrected before the script would run.
But the nice thing about AI is that if you don’t write scripts all the time and/or don’t have the world’s greatest memory, it remembers all those arcane Linux commands and their options, and mostly uses them correctly. For example, that line latest_dir=$(find "/storage/location/of/timeshift/snapshots-monthly" -mindepth 1 -maxdepth 1 \( -type d -o -type l \) -printf '%T@ %p\n' | sort -n | tail -1 | cut -d' ' -f2-)
had some issues the first time around, but with a little prompting and feedback (explaining what was going wrong to the AI) it finally came up with a working line. Someone who writes bash scripts for a living and who can remember all those Linux commands and their options might have been able to come up with a working line faster than the AI did, but we do not write bash scripts for a living, and this would have probably taken hours (maybe even days) without AI assistance. Oh, and the AI never gives you attitude or snark when providing you with answers, which is more than can be said about most online Linux forums.
By the time you read this there may be much better online AI interfaces available, and in particular ones designed for creating code (that are not tucked away in some space that either requires payment, or that you give up personal information such as your telephone number). It will be interesting to see if AI continues to make it easier for casual Linux users to create short scripts or programs such as these.