You're new to Linux and don't have a backup strategy. You never know when you'll bork your fresh Linux install or loose data in the multitude of ways possible.
If this is an issue you'd like to mitigate, then continue reading.
A good backup strategy is important to safeguard your data against possible data loss, malware or theft.
An ideal backup tool does not exist. What works for me might very well not work for you. I assume that your setup doesn't have any fancy NAS server or an extra Linux box. This is a simple intentional backup process that is a step above copying files from A to B.
You should absolutely do more than this blog post, but this is a good place to start.
If you knew me, you'd know I'd start with rsync
. Before you continue, have a quick look at its man-page. rsync
is an easy tool to use, once you figure out its options. The problem is there is no way you are remembering it and using all its tedious options and so, we script.
Let's break this into steps:
- Labelling your block device
- Reliably mount and dismount disks attached to your system - it can be a flash drive, external HDD or SSD
- A way to template the backup process, making it easier to add future directories to backup.
Labelling your block device
I'd rather not go over the details of changing a label in this post. There are much better sources for it. I personally prefer the examples given in this Arch Wiki page.
Sourcing bash functions
Bash is a command processor, we can run scripts and and interactive commands with bash. This tutorial will not speak on Bash, there's a bunch of tutorials and documentation available on the internet - Check here and here.
Knowing how to source bash functions is an important prerequisite for this article. In essence we need only to source
a bash script that defines a set of bash functions, like so
source /path/to/script # or
. /path/to/another-script
You can source a script in your ~/.bash_profile
,~/.bashrc
or save these scripts to $XDG_CONFIG_HOME/bash/functions.d
and add the below command to dynamically source all scripts.
As we get into the article you'll see me define bash functions, make sure you source them into your bash config!
Map partitions to a root directory
A precursor to the template __bac
bash function is defining the mount paths of the possible disks that we intend to store our backups.
Templating with the __bac function
I started with the template backup __bac
bash function. This is very helpful to quickly change the parameters of rsync
and reuse this function for various targets and sources.
We use a few rsync
options to preserve permissions and links and delete target files that no longer exist in SOURCE_DIR
Exploring the rsync
man page should give you a better explanation of what these options do.
We now create a few more helper functions. I set the general scheme of other bash functions that call upon __bac
to be __bac-app-*
. For example,
To make it even easier I added a bash function that dynamically runs all __bac-app-*
bash functions.
__bac-apps() {
# Store list of `__bac-app-*` bash functions
apps=$(declare -F | awk '{print $NF}' | sort | grep "^__bac-app-[[:alpha:]]*")
# Iterate and run through it
for app in ${apps[@]}; do
${app} $1
done
}
Mounting and unmounting partitions
Before we expose bash functions to the user, we attempt at mounting a disk. I began by just using mount
/umount
to create bash functions which accept the block devices' label.
We use lsblk
, mtab
, mount
and umount
. These are preinstalled tools that come with any distro. If you don't find them on whatever bespoke Linux distribution you use, feel free to install them and make sure it's available in your PATH
.
We now expose the user facing bash function that a user, script or cron job can call upon. Now we use our util-mount-disk
& util-unmount-disk
bash functions.
bac-disk() {
if ! util-mount-disk $1; then
return 1
fi
echo -e ">> Backing up to disk $1"
__bac-apps $1
echo -e ""
util-unmount-disk $1
}
To make things even easier, we call upon another function to pass all labels at once.
bac-all() {
bac-disk disk-1
bac-disk example
bac-disk some-partition-label
}
We're done!
Just run bac-all
on your shell or run bac-disk <YOUR_DISK_LABEL>
.