backup-rotate.sh
Инкрементальный бэкап директорий с автоматической ротацией. Использует rsync с hard links для экономии места. Хранит заданное количество последних копий, остальные удаляет.
Зависимости
rsync(обычно уже установлен)bash 4+
Использование
chmod +x backup-rotate.sh ./backup-rotate.sh /path/to/source /path/to/backups 7
Третий аргумент — количество хранимых копий (по умолчанию 7).
Код
#!/usr/bin/env bash
set -euo pipefail
# backup-rotate.sh — инкрементальный бэкап с ротацией
# Использование: ./backup-rotate.sh <source> <dest> [keep=7]
SOURCE="${1:?Укажите директорию-источник}"
DEST="${2:?Укажите директорию для бэкапов}"
KEEP="${3:-7}"
DATE=$(date +%Y-%m-%d_%H-%M-%S)
BACKUP_DIR="$DEST/$DATE"
LATEST_LINK="$DEST/latest"
# Создаём директорию для бэкапов, если не существует
mkdir -p "$DEST"
# rsync с hard links от предыдущего бэкапа
if [ -L "$LATEST_LINK" ]; then
rsync -a --delete --link-dest="$LATEST_LINK" "$SOURCE/" "$BACKUP_DIR/"
else
rsync -a --delete "$SOURCE/" "$BACKUP_DIR/"
fi
# Обновляем симлинк на последний бэкап
rm -f "$LATEST_LINK"
ln -s "$BACKUP_DIR" "$LATEST_LINK"
# Ротация: удаляем старые бэкапы
cd "$DEST"
BACKUPS=($(ls -d 20[0-9][0-9]-* 2>/dev/null | sort))
while [ "${#BACKUPS[@]}" -gt "$KEEP" ]; do
echo "Удаляю старый бэкап: ${BACKUPS[0]}"
rm -rf "${BACKUPS[0]}"
BACKUPS=("${BACKUPS[@]:1}")
done
echo "Бэкап завершён: $BACKUP_DIR"
echo "Всего копий: ${#BACKUPS[@]} (лимит: $KEEP)"Автоматизация через cron
Добавьте в crontab -e:
# Ежедневный бэкап в 3:00 0 3 * * * /opt/scripts/backup-rotate.sh /var/www /backups/www 14