Handy bash backup script
Making regular backups is a must! If you're still one of those people who remain unconvinced of this, then a) I envy you and b) Just wait for your first hardware-related disaster to happen - you'll sing a different tune. I, for one, have set up a simple bash script that automates syncing my home directory with an external hard drive every month.
You never know when your hard drive or SSD is going to give up the spirit. When it does, the consequences are entirely dependent on your previous actions. I like to follow the 3-2-1 backup strategy.
3-2-1 backup strategy
This is a data protection strategy that's simple enough for a 'normal' person to use, yet offers robust protection for your personal data. It's easy to remember:
- Maintain three copies of your data - one can be the main copy on your personal computer, but you need at least two more copies.
- Use two different types of media - say, keep one copy on an external hard drive, and the other in the cloud.
- Keep one copy in a secondary location - just imagine that there's a fire and both your PC and the external hard drive you keep in your drawer burn down? This can be a server in the cloud, or... keep the external HDD at your parents' house :)
Personally, I went with the path of least resistance: I have a copy of my most important files uploaded on OneDrive, and an external drive onto which I regularly upload my entire /home directory.
Backup script
Now, theoretically I could just remember to backup my all files regularly. Unfortunately, mother nature has gifted me with a rather fickle memory. Besides, automation is fun! That's why I have a bash script scheduled to run on the 1st of every month, not only reminding me to make the backup, but also actually running it for me. I'll share the script with you - but don't blindly trust me, (or any script you download from the Internet, really). Be sure to go through it and figure out exactly what it does on your own!
This should work on any Linux distribution. I'm running Arch, btw.
First, as with any script, we specify the shell interpeter to use:
#!/bin/bash
Then, I want to check if the external drive is mounted. First, I'll send myself a reminder to actually do it:
echo "It's time for your monthly /home backup. Connect your external drive."
read -p "Press enter to continue..."
if [ ! -d "/run/media/maciejk/Data2/" ]; then
echo "External hard drive is not mounted."
exit 1
fi
You need to change the path to your own external HDD's mounting point.As you see, if the drive still isn't mounted, then the script exits. If it is mounted, then we begin to copy everything over. We'll also have a nice message at the end, indicating if everything went according to plan:
rsync -avh --progress /home/maciejk/ /run/media/maciejk/Data2/homebackup
if [ $? -eq 0 ]; then
echo "Backup completed successfully."
else
echo "Backup failed."
fi
Again, change the paths to suit your own purposes. Save the script to a convenient place - ~/bin works just fine. Remember to add .sh at the end of your filename.
And that's it, that's the basic version of the script. For it to run automatically, you will need to schedule its execution using cron:
crontab -e
And add a new line to your crontab file:
0 20 1 * * /path/to-yourscript.sh
You will need to replace /path/to-yourscript.sh with the path to your script, of course. This runs the script at 20:00 every first day of the month. If you want to run the script on a different timeline, I recommend using fcrontab.guru to generate your own version of this line.
Backing up my packages
All this isn't enough for me. I have my /home directory backed up, but what if I need to reinstall my system from scratch? Do I have to remember what packages I had installed? No, we can save a list of installed packages as well by adding the following line to our script, right before the rsync operation:
pacman -Qqe > ~/.myPackages.txt
This is on Arch - any Arch-based distro will support this, but for apt or dnf, you'll have to figure it out on your own. Sorry!
What this does is create a list of all your explicitly installed packages - that is those that you, yourself have installed so far. If you ever need to reinstall everything from scratch, simply run:
pacman -S --needed - < ~/.myPackages.txt
And everything that was installed at the moment you made your backup should be restored.
Summary
So, to summarize - here's the complete version of my script. Remember to change the paths to reflect your own filesystem!
#!/bin/bash
# Display a message prompting the user to plug in the external drive
echo "It's time for your monthly /home backup. Plug your external drive in and press enter to continue."
read -p "Press enter to continue..."
# Check if the external hard drive is mounted
if [ ! -d "/run/media/maciejk/Data2/" ]; then
echo "External hard drive is not mounted."
exit 1
fi
# Create a list of explicitly installed packages
echo "Drive detected, creating package list..."
pacman -Qqe > ~/.myPackages.txt
# Copy the entire home directory to the external hard drive
rsync -avh --progress /home/maciejk/ /run/media/maciejk/Data2/homebackup
# Check if rsync was successful
if [ $? -eq 0 ]; then
echo "Backup completed successfully."
else
echo "Backup failed."
fi