Выполнение регулярных резервных копий ваших файлов в операционных системах Linux является важной частью безопасности персональных данных и общей практики управления системой. Независимо от того, являетесь ли вы ответственным за свой персональный ноутбук, управление серверами разработки или производственной среды, создание регулярных резервных копий дает вам спокойствие, зная, что ваши критические данные безопасны от непредвиденных системных катастроф, таких как отказы диска, атаки вредоносных программ или случайные удаления.

В следующих параграфах мы пройдем вас через создание простого, но мощного сценария, который может быть использован для автоматизации резервного копирования важных каталогов в Linux-машине. Сценарий предоставит несколько переменных конфигурации, таких как резервное назначение, каталоги для резервного копирования, требуемое дисковое пространство для резервного копирования, формат даты, флаг сжатия и период резервного хранения. Он удалит простой в использовании сценарий и может быть назначен с помощью cron для запуска в заданный промежуток времени.

Правило 3-2-1

Правило резервного копирования 3-2-1 гласит, что вам нужны три копии ваших данных. В дополнение к основной рабочей копии вам нужны две резервные копии, хранящиеся на разных типах носителей, одна из которых должна быть вне дома. С этой системой вы вряд ли потеряете свои данные.

Создание сценария Bash

Создайте сценарий в /usr/local/bin/ или каталоге домашних пользователей.

1
$ sudo nano /usr/local/bin/backup_rotate.sh

Вставьте следующие строки кода:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
#!/usr/bin/env bash

# =====================================================================
# Linux System Backup Script
# =====================================================================
# Описание: Этот сценарий создает резервную копию важных системных каталогов, сжимает их с помощью tar, и включает в себя временные метки для простой идентификации.
# Скрипт: ./backup_rotate.sh [config_file]
# =====================================================================

# =====================================================================
# CONFIGURATION
# =====================================================================
# Default configuration (can be overridden by config file)
BACKUP_DIR="/backup"                        # Where backups are stored
DIRECTORIES_TO_BACKUP=("/etc" "/home" "/root" "/var/log" "/opt")  # Directories to backup
EXCLUDE_PATTERNS=("*.tmp" "*.swp" "/home/*/Downloads" "/home/*/Trash")  # Patterns to exclude
RETENTION_DAYS=30                           # How many days to keep backups
LOG_FILE="/var/log/system_backup.log"       # Log file location
DATE_FORMAT="%Y-%m-%d_%H-%M-%S"             # Format for date in backup name
COMPRESSION_TYPE="gzip"                     # Options: gzip, bzip2, xz
REQUIRED_SPACE_GB=10                         # Required free space in GB

# =====================================================================
# FUNCTIONS
# =====================================================================

# Function to write log messages
log() {
    local level="$1"
    local message="$2"
    local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
    
    # Echo to console with color
    case "$level" in
        "INFO")
            echo -e "\e[32m[INFO]\e[0m $message"  # Green
            ;;
        "WARNING")
            echo -e "\e[33m[WARNING]\e[0m $message"  # Yellow
            ;;
        "ERROR")
            echo -e "\e[31m[ERROR]\e[0m $message"  # Red
            ;;
        ,*)
            echo -e "[${level}] $message"
            ;;
    esac
    
    # Append to log file
    if [ -w "$(dirname "$LOG_FILE")" ]; then
        echo "[$timestamp] [${level}] $message" >> "$LOG_FILE"
    else
        echo -e "\e[31m[ERROR]\e[0m Cannot write to log file $LOG_FILE" >&2
    fi
}

# Function to load configuration from file
load_config() {
    local config_file="$1"
    if [ -f "$config_file" ]; then
        log "INFO" "Loading configuration from $config_file"
        source "$config_file"
    else
        log "WARNING" "Configuration file $config_file not found. Using defaults."
    fi
}

# Function to check for root privileges
check_root() {
    if [ "$(id -u)" -ne 0 ]; then
        log "ERROR" "This script must be run as root to properly backup system files"
        exit 1
    fi
}

# Function to check available disk space
check_disk_space() {
    # Convert GB to KB (1GB = 1048576KB)
    local required_space_kb=$((REQUIRED_SPACE_GB * 1048576))
    local available_space=$(df -k "$BACKUP_DIR" | awk 'NR==2 {print $4}')
    local available_space_gb=$(echo "scale=2; $available_space / 1048576" | bc)
    
    if [ "$available_space" -lt "$required_space_kb" ]; then
        log "ERROR" "Not enough disk space. Required: ${REQUIRED_SPACE_GB}GB, Available: ${available_space_gb}GB"
        exit 1
    else
        log "INFO" "Sufficient disk space available: ${available_space_gb}GB"
    fi
}

# Function to create backup directory if it doesn't exist
create_backup_dir() {
    if [ ! -d "$BACKUP_DIR" ]; then
        log "INFO" "Creating backup directory: $BACKUP_DIR"
        mkdir -p "$BACKUP_DIR"
        
        if [ $? -ne 0 ]; then
            log "ERROR" "Failed to create backup directory: $BACKUP_DIR"
            exit 1
        fi
    fi
}

# Function to create the backup
create_backup() {
    local timestamp=$(date +"$DATE_FORMAT")
    local hostname=$(hostname)
    local backup_file="${BACKUP_DIR}/system_backup_${hostname}_${timestamp}.tar"
    local exclude_args=""
    
    # Build exclude arguments
    for pattern in "${EXCLUDE_PATTERNS[@]}"; do
        exclude_args="$exclude_args --exclude='$pattern'"
    done
    
    # Add appropriate compression extension and option
    case "$COMPRESSION_TYPE" in
        "gzip")
            backup_file="${backup_file}.gz"
            compression_opt="-z"
            ;;
        "bzip2")
            backup_file="${backup_file}.bz2"
            compression_opt="-j"
            ;;
        "xz")
            backup_file="${backup_file}.xz"
            compression_opt="-J"
            ;;
        ,*)
            backup_file="${backup_file}.gz"
            compression_opt="-z"
            ;;
    esac
    
    log "INFO" "Starting backup to $backup_file"
    log "INFO" "Backing up: ${DIRECTORIES_TO_BACKUP[*]}"
    
    # Create the backup command
    # We use eval because we need to expand the exclude_args array
    backup_cmd="tar $compression_opt -cvf \"$backup_file\" $exclude_args ${DIRECTORIES_TO_BACKUP[*]} 2>/tmp/backup_errors.log"
    
    log "INFO" "Executing: $backup_cmd"
    
    # Execute backup command
    eval $backup_cmd
    
    # Check for errors
    if [ $? -eq 0 ]; then
        log "INFO" "Backup completed successfully: $backup_file"
        log "INFO" "Backup size: $(du -h "$backup_file" | cut -f1)"
        
        # Store list of backed up files
        log "INFO" "Creating file list..."
        tar -tvf "$backup_file" > "${backup_file%.tar.*}.file_list.txt" 2>/dev/null
    else
        log "ERROR" "Backup failed! Check /tmp/backup_errors.log for details"
        
        if [ -f "/tmp/backup_errors.log" ]; then
            log "ERROR" "Errors during backup: $(cat /tmp/backup_errors.log)"
        fi
        
        exit 1
    fi
}

# Function to delete old backups
clean_old_backups() {
    if [ "$RETENTION_DAYS" -gt 0 ]; then
        log "INFO" "Cleaning backups older than $RETENTION_DAYS days"
        find "$BACKUP_DIR" -name "system_backup_*.tar.*" -mtime +$RETENTION_DAYS -delete
        
        if [ $? -eq 0 ]; then
            log "INFO" "Old backups cleaned successfully"
        else
            log "WARNING" "Failed to clean old backups"
        fi
    else
        log "INFO" "Backup retention disabled"
    fi
}

# =====================================================================
# MAIN SCRIPT
# =====================================================================

# Load configuration from file if provided
if [ $# -gt 0 ]; then
    load_config "$1"
fi

# Check if running as root
check_root

# Begin backup process
log "INFO" "=== BACKUP STARTED ==="

# Create backup directory if it doesn't exist
create_backup_dir

# Check available disk space
check_disk_space

# Create the backup
create_backup

# Clean old backups
clean_old_backups

log "INFO" "=== BACKUP COMPLETED ==="

exit 0

Основные функции сценария

  1. Конфигурация:
  • Настраиваемое резервное местоположение, каталоги для резервного копирования и период хранения
  • Исключает общие ненужные файлы (*.tmp, *.swp и т.д.)
  • Поддержка различных типов сжатия (gzip, bzip2, xz)
  1. Особенности безопасности:
  • Проверка корневых привилегий
  • Проверка доступного дискового пространства
  • Включает обработку ошибок и регистрацию
  • Создает подробные журналы с таймерами
  1. Возможности резервного копирования:
  • Временные метки на именах
  • Настраиваемые варианты сжатия
  • Создает список резервных файлов
  • Автоматическая очистка старых резервных копий

Выполнение резервного копирования

Сделайте сценарий исполняемым:

1
$ sudo chmod +x /usr/local/bin/backup_rotate.sh

Отредактируйте ключевые переменные для настройки:

1
2
3
4
5
6
BACKUP_DIR="/backup"                                                    # Where backups are stored
DIRECTORIES_TO_BACKUP=("/etc" "/home" "/root" "/var/log" "/opt")        # Directories to backup
EXCLUDE_PATTERNS=("*.tmp" "*.swp" "/home/*/Downloads" "/home/*/Trash")  # Patterns to exclude
RETENTION_DAYS=30                                                       # How many days to keep backups
COMPRESSION_TYPE="gzip"                                                 # Options: gzip, bzip2, xz
REQUIRED_SPACE_GB=10                                                    # Required free space in GB

После изменений запустите сценарий, чтобы инициировать резервное копирование:

1
$ sudo ./usr/local/bin/backup_rotate.sh

Он проведет необходимые проверки перед копированием.

Если резервное копирование успешно выполняется без каких-либо ошибок, вы увидите следующее сообщение подтверждения в конце.

Автоматизация с помощью Cron

Расписания cron хранятся в файле с именем crontab. Типичная запись crontab начинается с пяти значений (или звездочек), за которыми следует команда. Значения сообщают cron, когда выполнять команду, а звездочка означает «все».

1
2
3
4
5
6
7
8
* * * * * команда, которая должна быть выполнена
- - - - -
| | | | |
| | | | ----- День недели (0 - 7) (воскресенье = 0 или 7)
| | | ------- Месяц (1 - 12)
| | --------- День месяца (1 - 31)
| ----------- Час (0 - 23)
-------------- Минута (0 - 59)

Чтобы отредактировать crontab, выполните:

1
$ sudo crontab -e

И добавьте строку:

1
0 3 * * * /usr/local/bin/backup_rotate.sh

Это запланирует cron для запуска команды в 3:00, каждый день любого месяца.

Убедитесь, что сценарий имеет исполняемые разрешения.

Завершение

Вы успешно настроили автоматизированное резервное копирование с помощью сценария Bash на Linux с использованием Cron. Автоматизация сценариев Bash позволяет выполнять общие задачи системного администрирования, такие как резервное копирование. Чтобы упростить управление системой, создайте несколько сценариев Bash и заданий Cron, указав необходимые команды для каждого.

Вы можете поделиться статьей со своими друзьями в социальных сетях, которым может быть интересна эта статья или просто оставить комментарий ниже. Спасибо.