Rewrote server backup shell script by adding a main function
Hello, I'm Munou.
I rewrote the shell script for creating backups that I wrote a while ago.
Introduction
I wrote this a while ago, but looking at it again, I realized I hadn't included code to delete old backed-up tar.gz files, and it seemed like it was going to get a bit long, so I refactored it into a main function.
For a lazy person like me, it's important to keep things as short as possible, so I tried rewriting it.
Ideally, I'd make it more versatile by allowing the backup destination and source to be specified as arguments, which would also make it clearer when written in cron, so I'll do that eventually.
Dissection
#!/bin/bash
MOUNT_DIR="/your/mount/point"
SRC_DIR="/want/to/backup/dir"
BK_DIR="backupdir"
EXCLUDE_FILE="" # Specify exclude file --exclude=your/path
W_DIR=`echo $SRC_DIR | awk -F/ '{print $(NF)}'`
# Check mount point, and mount if not mounted
check_mount() {
df | grep "$MOUNT_DIR" > /dev/null
if [ $? -ne 0 ]; then
break
else
mount $MOUNT_DIR || exit 1
fi
}
# Delete old backup files
rm_old_backups() {
BK_COUNT=`ls -1 $MOUNT_DIR/$BK_DIR/*.tar.gz 2>/dev/null | wc -l`
if [ "$BK_COUNT" -ge 3 ]; then
ls -1t $MOUNT_DIR/$BK_DIR/*.tar.gz | tail -n +4 | while read file; do
rm -f "$file"
done
fi
}
# Create backup
create_backup() {
rsync -av $EXCLUDE_FILE $SRC_DIR $MOUNT_DIR/$BK_DIR
tar cfz $MOUNT_DIR/$BK_DIR/"$W_DIR"_`date +"%Y%m%d"`.tar.gz -C $MOUNT_DIR/$BK_DIR $W_DIR
rm -rf $MOUNT_DIR/$BK_DIR/$W_DIR/*
}
main() {
check_mount # Check mount, mount if necessary
mkdir -p $MOUNT_DIR/$BK_DIR # Create backup directory
rm_old_backups # Delete old backups
create_backup # Create new backup
umount $MOUNT_DIR || exit 1 # Unmount
}
main
Since I'm assuming mounting/unmounting, I needed to include that check. It's strange, but there's a mountpoint command that can determine if something is mounted, but when I tried it, it sometimes showed 'not mounted' even when it was, and I couldn't get a proper return value.
So, I thought, if it's not mounted, it won't appear in the df output. Therefore, checking the return value after grepping the df standard output for the mount point should be quite reliable, I guess...
Originally, I simply copied with the cp command and then compressed with tar, but I wanted to specify "exclude files for copying", and it seems rsync can do that. That's why everyone is starting to use rsync.
The reason I explicitly specified $W_DIR was that I needed to create the value for use with rsync.
The key part is the logic for deleting old tar.gz files. I tried it because I felt that checking with ls instead of greedily looking into subdirectories with find would put less load on disk I/O and be safer.
And by getting the filenames with tail, I can clearly decide how many files to allow, which I think is quite good.
Conclusion
Well, honestly, I don't think it was strictly necessary to put it into a main function, but I feel it ended up being more readable, so I'll consider it a success.
That's all for now. Until next time.