如何编写自动备份系统状态脚本

wen 实用脚本 2

本文目录导读:

如何编写自动备份系统状态脚本

  1. 基础系统状态备份脚本
  2. 带增量备份的高级版本
  3. 定时执行配置 (crontab)
  4. 使用Systemd定时器
  5. 使用说明

我来为您提供一个系统状态自动备份脚本的完整方案,包含多种备份场景。

基础系统状态备份脚本

#!/bin/bash
# 系统状态自动备份脚本包括:系统配置、服务状态、重要文件等
# 配置参数
BACKUP_DIR="/var/backups/system-state"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_NAME="system-state-$DATE"
LOG_FILE="/var/log/system-backup.log"
RETENTION_DAYS=30
# 创建备份目录
mkdir -p "$BACKUP_DIR/$BACKUP_NAME"
# 日志函数
log_message() {
    local msg="[$(date '+%Y-%m-%d %H:%M:%S')] $1"
    echo "$msg" | tee -a "$LOG_FILE"
}
# 备份系统配置文件
backup_system_configs() {
    log_message "开始备份系统配置文件..."
    # 备份网络配置
    cp -r /etc/network "$BACKUP_DIR/$BACKUP_NAME/networking/" 2>/dev/null || true
    # 备份SSH配置
    cp -r /etc/ssh "$BACKUP_DIR/$BACKUP_NAME/ssh/" 2>/dev/null || true
    # 备份主机名和hosts文件
    cp /etc/hostname "$BACKUP_DIR/$BACKUP_NAME/" 2>/dev/null || true
    cp /etc/hosts "$BACKUP_DIR/$BACKUP_NAME/" 2>/dev/null || true
    # 备份crontab
    crontab -l > "$BACKUP_DIR/$BACKUP_NAME/crontab.txt" 2>/dev/null || true
    # 备份系统服务状态
    systemctl list-units --type=service --all > "$BACKUP_DIR/$BACKUP_NAME/services.txt" 2>/dev/null || true
    log_message "系统配置文件备份完成"
}
# 备份系统信息
backup_system_info() {
    log_message "备份系统信息..."
    # 系统基本信息
    uname -a > "$BACKUP_DIR/$BACKUP_NAME/system_info.txt"
    cat /etc/os-release >> "$BACKUP_DIR/$BACKUP_NAME/system_info.txt" 2>/dev/null || true
    # 磁盘使用情况
    df -h > "$BACKUP_DIR/$BACKUP_NAME/disk_usage.txt"
    # 内存使用情况
    free -h > "$BACKUP_DIR/$BACKUP_NAME/memory_usage.txt"
    # 运行进程
    ps aux --sort=-%mem | head -50 > "$BACKUP_DIR/$BACKUP_NAME/top_processes.txt"
    # 网络连接
    ss -tuln > "$BACKUP_DIR/$BACKUP_NAME/network_connections.txt"
    # 已安装软件包
    if command -v dpkg &> /dev/null; then
        dpkg -l > "$BACKUP_DIR/$BACKUP_NAME/installed_packages.txt"
    elif command -v rpm &> /dev/null; then
        rpm -qa --qf="%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n" > "$BACKUP_DIR/$BACKUP_NAME/installed_packages.txt"
    fi
    log_message "系统信息备份完成"
}
# 备份用户和权限
backup_users_permissions() {
    log_message "备份用户和权限信息..."
    # 用户列表
    cat /etc/passwd > "$BACKUP_DIR/$BACKUP_NAME/users.txt"
    # 用户组
    cat /etc/group > "$BACKUP_DIR/$BACKUP_NAME/groups.txt"
    # sudoers配置
    cp /etc/sudoers "$BACKUP_DIR/$BACKUP_NAME/sudoers" 2>/dev/null || true
    cp -r /etc/sudoers.d "$BACKUP_DIR/$BACKUP_NAME/sudoers.d/" 2>/dev/null || true
    # 重要文件的权限
    ls -la /etc/shadow /etc/gshadow /etc/passwd /etc/group > "$BACKUP_DIR/$BACKUP_NAME/important_permissions.txt"
    log_message "用户和权限备份完成"
}
# 创建压缩包
create_archive() {
    log_message "创建压缩备份包..."
    cd "$BACKUP_DIR"
    tar -czf "$BACKUP_NAME.tar.gz" "$BACKUP_NAME/"
    # 删除临时目录
    rm -rf "$BACKUP_NAME"
    # 计算校验和
    md5sum "$BACKUP_NAME.tar.gz" > "$BACKUP_NAME.tar.gz.md5"
    log_message "备份包创建完成: $BACKUP_DIR/$BACKUP_NAME.tar.gz"
}
# 清理旧备份
cleanup_old_backups() {
    log_message "清理旧备份..."
    find "$BACKUP_DIR" -name "system-state-*.tar.gz" -mtime +$RETENTION_DAYS -exec rm {} \;
    find "$BACKUP_DIR" -name "system-state-*.tar.gz.md5" -mtime +$RETENTION_DAYS -exec rm {} \;
    log_message "旧备份清理完成"
}
# 发送通知(可选)
send_notification() {
    local status="$1"
    local message="系统备份状态: $status\n备份文件: $BACKUP_DIR/$BACKUP_NAME.tar.gz"
    # 可以添加邮件通知等
    # echo -e "$message" | mail -s "系统备份通知" admin@example.com
    log_message "通知发送"
}
# 主函数
main() {
    log_message "=== 开始系统状态备份 ==="
    # 检查磁盘空间
    local available_space=$(df "$BACKUP_DIR" | awk 'NR==2 {print $4}')
    if [ "$available_space" -lt 1048576 ]; then  # 1GB in KB
        log_message "错误: 磁盘空间不足"
        send_notification "失败"
        exit 1
    fi
    # 执行备份
    backup_system_configs
    backup_system_info
    backup_users_permissions
    create_archive
    cleanup_old_backups
    log_message "=== 系统状态备份完成 ==="
    send_notification "成功"
}
# 执行主函数
main

带增量备份的高级版本

#!/bin/bash
# 高级系统状态备份脚本
# 支持增量备份和加密
# 配置
BACKUP_DIR="/var/backups/system-state"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_NAME="sysbackup-$DATE"
SNAPSHOT_DIR="$BACKUP_DIR/snapshots"
ENCRYPTION_KEY="your-encryption-key-here"  # 使用环境变量替代
LOG_FILE="/var/log/system-backup.log"
RETENTION_DAYS=7
MAX_BACKUPS=10
# 备份清单
declare -A BACKUP_ITEMS
BACKUP_ITEMS=(
    ["/etc"]="配置文件"
    ["/var/log"]="日志文件"  
    ["/home"]="用户数据"
    ["/var/www"]="Web服务器"
    ["/var/lib/mysql"]="MySQL数据"
)
# 函数:检查并创建目录
ensure_directory() {
    local dir="$1"
    if [ ! -d "$dir" ]; then
        mkdir -p "$dir"
        log "创建目录: $dir"
    fi
}
# 函数:日志记录
log() {
    local msg="[$(date '+%Y-%m-%d %H:%M:%S')] $1"
    echo "$msg" | tee -a "$LOG_FILE"
}
# 函数:检查系统资源
check_resources() {
    # 检查磁盘空间
    local space=$(df "$BACKUP_DIR" | awk 'NR==2 {print $5}' | sed 's/%//')
    if [ "$space" -gt 90 ]; then
        log "警告: 磁盘使用率超过90%"
        return 1
    fi
    # 检查CPU负载
    local load=$(uptime | awk -F'load average:' '{print $2}' | cut -d, -f1)
    if (( $(echo "$load > 5" | bc -l) )); then
        log "警告: 系统负载过高: $load"
        return 1
    fi
    return 0
}
# 函数:执行增量备份
perform_incremental_backup() {
    local source="$1"
    local basename=$(basename "$source")
    local dest="$BACKUP_DIR/$BACKUP_NAME/$basename"
    local snapshot="$SNAPSHOT_DIR/$basename.snar"
    ensure_directory "$(dirname "$dest")"
    # 检查是否存在快照文件
    if [ -f "$snapshot" ]; then
        log "执行增量备份: $source"
        tar --listed-incremental="$snapshot" \
            -czf "$dest.tar.gz" \
            "$source" 2>/dev/null || return 1
    else
        log "执行完整备份: $source"
        ensure_directory "$(dirname "$snapshot")"
        tar --listed-incremental="$snapshot" \
            -czf "$dest.tar.gz" \
            "$source" 2>/dev/null || return 1
    fi
}
# 函数:加密备份
encrypt_backup() {
    local file="$1"
    if [ -n "$ENCRYPTION_KEY" ] && command -v openssl &> /dev/null; then
        log "加密备份: $file"
        openssl enc -aes-256-cbc -salt \
            -in "$file" \
            -out "$file.enc" \
            -pass pass:"$ENCRYPTION_KEY" 2>/dev/null
        rm "$file"
        log "加密完成: $file.enc"
    fi
}
# 函数:备份数据库(如果存在)
backup_databases() {
    # MySQL
    if command -v mysqldump &> /dev/null; then
        log "备份MySQL数据库..."
        ensure_directory "$BACKUP_DIR/$BACKUP_NAME/databases/mysql"
        mysql -e "SHOW DATABASES;" | grep -v Database | while read db; do
            mysqldump --single-transaction "$db" > \
                "$BACKUP_DIR/$BACKUP_NAME/databases/mysql/$db.sql" 2>/dev/null
        done
    fi
    # PostgreSQL
    if command -v pg_dumpall &> /dev/null; then
        log "备份PostgreSQL数据库..."
        ensure_directory "$BACKUP_DIR/$BACKUP_NAME/databases/postgres"
        pg_dumpall > "$BACKUP_DIR/$BACKUP_NAME/databases/postgres/all.sql" 2>/dev/null
    fi
}
# 函数:创建备份报告
create_backup_report() {
    local report_file="$BACKUP_DIR/$BACKUP_NAME/backup_report.txt"
    cat > "$report_file" << EOF
系统备份报告
==============
备份时间: $(date)
主机名: $(hostname)
备份类型: $([ -d "$SNAPSHOT_DIR" ] && echo "增量" || echo "完整")
系统信息:
- 操作系统: $(cat /etc/os-release 2>/dev/null | grep PRETTY_NAME | cut -d'"' -f2)
- 内核版本: $(uname -r)
- 运行时间: $(uptime -p)
$(for item in "${!BACKUP_ITEMS[@]}"; do
    echo "- $item (${BACKUP_ITEMS[$item]})"
done)
备份大小:
$(du -sh "$BACKUP_DIR/$BACKUP_NAME" 2>/dev/null | awk '{print $1 " 总大小"}')
EOF
}
# 主函数
main() {
    local start_time=$(date +%s)
    log "================================="
    log "开始系统备份"
    log "================================="
    # 检查资源
    if ! check_resources; then
        log "资源检查失败,停止备份"
        exit 1
    fi
    # 创建备份目录
    ensure_directory "$BACKUP_DIR/$BACKUP_NAME"
    # 执行备份
    for item in "${!BACKUP_ITEMS[@]}"; do
        if [ -d "$item" ]; then
            log "备份 ${BACKUP_ITEMS[$item]}: $item"
            if ! perform_incremental_backup "$item"; then
                log "警告: 备份失败 $item"
            fi
        fi
    done
    # 备份数据库
    backup_databases
    # 创建报告
    create_backup_report
    # 创建归档
    log "创建完整归档..."
    tar -czf "$BACKUP_DIR/$BACKUP_NAME.tar.gz" \
        -C "$BACKUP_DIR" "$BACKUP_NAME"
    # 加密
    encrypt_backup "$BACKUP_DIR/$BACKUP_NAME.tar.gz"
    # 清理临时文件
    rm -rf "$BACKUP_DIR/$BACKUP_NAME"
    # 清理旧备份
    log "清理旧备份..."
    find "$BACKUP_DIR" -name "sysbackup-*.tar.gz" -mtime +$RETENTION_DAYS | sort | head -n -$MAX_BACKUPS | xargs rm -f
    local end_time=$(date +%s)
    local duration=$((end_time - start_time))
    log "备份完成,耗时: $duration 秒"
    log "备份位置: $BACKUP_DIR"
    log "================================="
}
# 错误处理
trap 'log "备份脚本被中断"; exit 1' SIGINT SIGTERM
# 执行
main $@

定时执行配置 (crontab)

# 编辑crontab配置
sudo crontab -e
# 添加以下配置
# 每天凌晨2点执行完整备份
0 2 * * * /usr/local/bin/system-backup.sh
# 每6小时执行一次增量备份
0 */6 * * * /usr/local/bin/system-backup-incremental.sh
# 每周一凌晨3点清理日志和旧备份
0 3 * * 1 /usr/local/bin/cleanup-backups.sh

使用Systemd定时器

# /etc/systemd/system/system-backup.service
[Unit]
Description=System State Backup Service
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/system-backup.sh
User=root
Environment=ENCRYPTION_KEY=your_key_here
[Install]
WantedBy=multi-user.target
# /etc/systemd/system/system-backup.timer
[Unit]
Description=System Backup Timer
Requires=system-backup.service
[Timer]
OnCalendar=daily
Persistent=true
RandomizedDelaySec=1800
[Install]
WantedBy=timers.target

使用说明

# 1. 保存脚本
sudo cp system-backup.sh /usr/local/bin/
sudo chmod +x /usr/local/bin/system-backup.sh
# 2. 创建备份目录
sudo mkdir -p /var/backups/system-state
sudo chmod 750 /var/backups/system-state
# 3. 测试运行
sudo /usr/local/bin/system-backup.sh
# 4. 查看备份状态
ls -l /var/backups/system-state/
# 5. 配置定时任务(根据需要选择)
# 方法1: 使用crontab
sudo crontab -e
# 方法2: 使用systemd
sudo systemctl enable system-backup.timer
sudo systemctl start system-backup.timer

这个脚本提供了:

  • 完整的系统状态备份
  • 增量备份支持
  • 备份加密
  • 自动清理
  • 日志记录
  • 错误处理
  • 多种调度方式

请根据实际需求调整配置参数。

抱歉,评论功能暂时关闭!