Ротация бэкапов

Скрипт ротейтит файлы бэкапов. Коментарии внутри.

#!/bin/bash

declare -A ROTATE
declare -A ROTATE_TOTAL
declare -A ROTATE_WEEKLY_TOTAL

# Указываем какие папки надо резервировать, ключ массива будет новым именем. Например будет создана папка /var/backup/sql/daily/2024-07-29 и в нее перемещено все что подпадает под маску.
ROTATE[sql]=/var/backups/mysql/*
ROTATE[border]=/var/backups/beta/vm/border/*

# Если нужно изменить количество бэкапов для конкретной папки. Используем одинковый ключ, что в и массиве ROTATE
ROTATE_TOTAL[sql]=7
# Если нужно делать недельные бэкапы, то заполняем массив указывая количество. Папка бэкапа будет /var/backup/sql/weekly/2024-07-29. Важно понимать, что бэкап переносится в данный каталог раз в неделю и если в этот день бэкапа не было, ничего не перенесется.
ROTATE_WEEKLY_TOTAL[sql]=4

# Количество хранимых файлов по умолчанию для всех бэкапов
ROTATE_TOTAL_DEFAULT=4

# Каталог где храним новые бэкапы.
BACKUP_DIR=/var/backup

#Delete ald files
function delete_old_files {
    mkdir -p $2
    cd $2
    rm_dirs=`ls -t | tail -n +$1`
    if [ "$rm_dirs" != "" ]; then
        echo -n "Delete old backup dirs: \""
        echo $rm_dirs |xargs echo -n
        echo "\" from $2/"
        echo $rm_dirs | xargs rm -rf
    fi
}

show_free_size=0

for key in ${!ROTATE[@]}
do
    # Если файлов для бэкапа нет, просто пропускаем.
    list_files=`ls ${ROTATE[$key]} 2>/dev/null`
    if [[ "${list_files}" == "" ]]; then
    continue
    fi

    current_parent_backup_dir="${BACKUP_DIR}/$key/daily"

    total=$ROTATE_TOTAL_DEFAULT
    if [[ -v "ROTATE_TOTAL[$key]" ]] ; then
    total=${ROTATE_TOTAL[$key]}
    fi

    # Если нужно еженедельно сохранять бэкап
    if [[ -v "ROTATE_WEEKLY_TOTAL[$key]" ]] ; then
    # Если первый день подменяем пути и количество файлов
        if [ "`date +%u`" = "7" ]; then
        current_parent_backup_dir="${BACKUP_DIR}/$key/weekly"
        total=${ROTATE_WEEKLY_TOTAL[$key]}
    fi
    fi

    current_backup_dir="${current_parent_backup_dir}/`date +%Y-%m-%d`/"

    mkdir -p $current_backup_dir

    echo "Rotating file  ${ROTATE[$key]} to ${current_backup_dir}"

    mv ${ROTATE[$key]} ${current_backup_dir}

    echo "Backup size" `du -sh ${current_backup_dir} | awk '{ print $1 }'`

    # Ротейтим
    delete_old_files $total $current_parent_backup_dir

    show_free_size=1
done

if [[ "$show_free_size" == "1" ]] ; then
    echo "Free size"  `df -h / |tail -1| awk '{ print $4 }'`
fi

[ Править ]

@kiranananda