Day09 of #90DaysOfDevOps

·

4 min read

Hey everyone!👋 It's Day 09 of 90DaysOfDevOps. Today, we're going to learn how to back up a files using a shell script. The script will create timestamp backup zip files and copy all the files from the specified directory into these backup folders.

Today we're diving into an essential DevOps task—backing up directories using a shell script.

Plus, the script will have a cool feature to keep only the last 3 backups. This means if there are more than 3 backup folders, the oldest ones will be deleted, making sure you always have the most recent backups.

Let’s get started..!

Assume we have 5 files in data folder we want to store that data backup in backups folder using backup.sh script

Now, let’s write a script to achieve this task.

#!/bin/bash
display_usage(){
    echo "Usage: ./backup.sh <path to your source> <path to backup folder>"
}

if [ $# -eq 0 ]; then
    display_usage
fi

source_dir=$1
timestamp=$(date '+%Y-%m-%d-%H-%M-%S')
backup_dir=$2

create_backup(){
        zip -r "${backup_dir}/backup_${timestamp}.zip" "${source_dir}" > /dev/null

        if [ $? -eq 0 ];then
                echo "Backup Generated Successfully for ${timestamp}"
        fi
}
perform_rotation(){
        backups=($(ls -t "${backup_dir}/backup_"*.zip 2>/dev/null))


        if [ "${#backups[@]}" -gt 3 ]; then
                echo "Performing rotation for 3 days"

                backups_to_remove=("${backups[@]:3}")

                for backup in "${backups_to_remove[@]}";
                do
                        rm -f ${backup}
                done
        fi
}
create_backup
perform_rotation

Let’s break down the script.!

#!/bin/bash
display_usage(){
    echo "Usage: ./backup.sh <path to your source> <path to backup folder>"
}

if [ $# -eq 0 ]; then
    display_usage
fi

above script is a simple usage check. When the script is run without any arguments, it tells the user how to use it by printing a message that includes the expected input format: ./backup.sh <path to your source> <path to backup folder>.

source_dir=$1
timestamp=$(date '+%Y-%m-%d-%H-%M-%S')
backup_dir=$2

create_backup(){
        zip -r "${backup_dir}/backup_${timestamp}.zip" "${source_dir}" > /dev/null

        if [ $? -eq 0 ];then
                echo "Backup Generated Successfully for ${timestamp}"
        fi
}

$1: This refers to the first argument passed to the script by the user when running it. This value is stored in the variable source_dir

timestamp: This variable stores the current date and time, formatted as YYYY-MM-DD-HH-MM-SS using the date command.

$2: This refers to the second argument passed to the script, which is expected to be the path to the backup destination folder. This path is saved in the variablebackup_dir.

Coming towards function create_backup()

  • zip -r "${backup_dir}/backup_${timestamp}.zip" "${source_dir}": This command creates a zip file that contains the contents of source_dir and saves it to backup_dir with a name like backup_YYYY-MM-DD-HH-MM-SS.zip.

  • > /dev/null: This part ensures that any output or messages from the zip command are silenced and not shown on the terminal.

  • $?: This special variable contains the exit status of the last command executed

  • -eq 0: This is a conditional check that asks, "Did the previous command succeed?" If yes (meaning zip worked successfully), the script proceeds to print a success message.

  • echo "Backup Generated Successfully for ${timestamp}": If the zip command succeeded, this line prints a message to the terminal confirming that the backup was created, along with the timestamp for reference.

Now second function as perform_rotation()

perform_rotation(){
        backups=($(ls -t "${backup_dir}/backup_"*.zip 2>/dev/null))

        if [ "${#backups[@]}" -gt 3 ]; then
                echo "Performing rotation for 3 days"

                backups_to_remove=("${backups[@]:3}")

                for backup in "${backups_to_remove[@]}";
                do
                        rm -f ${backup}
                done
        fi
}
create_backup
perform_rotation
  • backups=($(ls -t "${backup_dir}/backup_"*.zip 2>/dev/null)): This command lists all the zip files (*.zip) in the backup_dir that match the pattern.

  • 2>/dev/null: This redirects any error messages to /dev/null, suppressing them.

  • ${#backups[@]}: This returns the number of elements in the backups array (i.e., the number of backup files found).

  • -gt 3: This checks if the number of backups is greater than 3. If more than 3 backups exist, the script proceeds to remove the oldest ones.

  • echo "Performing rotation for 3 days": This prints a message indicating that backup rotation is being performed, and only 3 of the most recent backups will be kept.

  • backups_to_remove=("${backups[@]:3}"):

    • This selects the elements from the backups array starting at index 3.

    • In other words, it skips the first 3 (newest) backups and stores the rest (older backups) in a new array called backups_to_remove.

    • for backup in "${backups_to_remove[@]}": This starts a loop that goes through each backup file in the backups_to_remove array.

    • rm -f ${backup}:

      • This command deletes the file (rm) specified by ${backup}, which is each old backup.
    • create_backup: This calls the function that creates a new backup.

    • perform_rotation: After the new backup is created, this function is called to ensure only the last 3 backups are retained, deleting any older ones.

Let’s run the script

Now let’s see the backup has been stored in backup folder or not..!

Backups are there…! When there are more than 3 backup files, the oldest ones will be deleted, making sure you always have the most recent backups.


Stay tuned for more insights as I continue my #90DayOfDevOps challenges. If you have any questions or tips, feel free to share them in the comments. Let’s keep learning and growing together! 🚀

Â