如何写一个简易的备份工具脚本

wen 实用脚本 1

本文目录导读:

如何写一个简易的备份工具脚本

  1. Python版本(推荐,功能更完善)
  2. Bash版本(简单实用)
  3. 使用方法
  4. 主要功能
  5. 扩展建议

我来提供一个功能完整但实现简单的备份工具脚本,这里提供Python和Bash两个版本:

Python版本(推荐,功能更完善)

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
简易备份工具脚本
功能:备份指定目录到目标位置,支持压缩和时间戳
"""
import os
import shutil
import datetime
import sys
import argparse
import hashlib
import json
class BackupTool:
    def __init__(self, source_dir, backup_dir, use_compress=True):
        """
        初始化备份工具
        :param source_dir: 要备份的源目录
        :param backup_dir: 备份文件存放的目标目录
        :param use_compress: 是否压缩备份
        """
        self.source_dir = os.path.abspath(source_dir)
        self.backup_dir = os.path.abspath(backup_dir)
        self.use_compress = use_compress
        # 生成时间戳
        self.timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
        self.backup_name = f"backup_{self.timestamp}"
        # 备份文件清单
        self.file_manifest = []
    def check_paths(self):
        """检查源目录和目标目录是否存在"""
        if not os.path.exists(self.source_dir):
            print(f"错误:源目录不存在 - {self.source_dir}")
            return False
        if not os.path.exists(self.backup_dir):
            print(f"创建备份目录:{self.backup_dir}")
            os.makedirs(self.backup_dir, exist_ok=True)
        return True
    def calculate_md5(self, filepath):
        """计算文件的MD5值"""
        hash_md5 = hashlib.md5()
        with open(filepath, "rb") as f:
            for chunk in iter(lambda: f.read(4096), b""):
                hash_md5.update(chunk)
        return hash_md5.hexdigest()
    def backup_with_copy(self):
        """直接复制方式备份"""
        try:
            # 创建带时间戳的目标文件夹
            dest_dir = os.path.join(self.backup_dir, self.backup_name)
            os.makedirs(dest_dir, exist_ok=True)
            # 复制所有内容
            for item in os.listdir(self.source_dir):
                src_path = os.path.join(self.source_dir, item)
                dest_path = os.path.join(dest_dir, item)
                if os.path.isdir(src_path):
                    shutil.copytree(src_path, dest_path)
                else:
                    shutil.copy2(src_path, dest_path)
                # 记录文件信息
                self.file_manifest.append({
                    'file': item,
                    'size': os.path.getsize(src_path)
                })
            print(f"备份完成!备份位置:{dest_dir}")
            return dest_dir
        except Exception as e:
            print(f"备份失败:{e}")
            return None
    def backup_with_compress(self):
        """压缩方式备份"""
        try:
            # 生成zip文件名
            zip_name = f"{self.backup_name}.zip"
            zip_path = os.path.join(self.backup_dir, zip_name)
            # 创建压缩文件
            shutil.make_archive(
                zip_path[:-4],  # 去掉.zip后缀
                'zip', 
                self.source_dir
            )
            print(f"备份完成!压缩文件位置:{zip_path}")
            # 保存文件清单
            manifest_path = os.path.join(self.backup_dir, f"{self.backup_name}_manifest.json")
            with open(manifest_path, 'w', encoding='utf-8') as f:
                json.dump(self.file_manifest, f, ensure_ascii=False, indent=2)
            return zip_path
        except Exception as e:
            print(f"备份失败:{e}")
            return None
    def save_backup_list(self, backup_path):
        """保存备份记录到日志"""
        log_file = os.path.join(self.backup_dir, "backup_history.json")
        # 读取现有记录
        try:
            with open(log_file, 'r', encoding='utf-8') as f:
                history = json.load(f)
        except:
            history = []
        # 添加新记录
        history.append({
            'timestamp': self.timestamp,
            'source': self.source_dir,
            'backup_path': backup_path,
            'size': self.get_directory_size(self.source_dir)
        })
        # 保存记录
        with open(log_file, 'w', encoding='utf-8') as f:
            json.dump(history, f, ensure_ascii=False, indent=2)
    def get_directory_size(self, directory):
        """计算目录大小"""
        total_size = 0
        for dirpath, dirnames, filenames in os.walk(directory):
            for filename in filenames:
                filepath = os.path.join(dirpath, filename)
                total_size += os.path.getsize(filepath)
        return total_size
    def run(self):
        """执行备份"""
        if not self.check_paths():
            return None
        print(f"开始备份...")
        print(f"源目录:{self.source_dir}")
        print(f"备份目录:{self.backup_dir}")
        if self.use_compress:
            result = self.backup_with_compress()
        else:
            result = self.backup_with_copy()
        if result:
            self.save_backup_list(result)
        return result
def main():
    # 设置命令行参数
    parser = argparse.ArgumentParser(description='简易备份工具')
    parser.add_argument('source', help='要备份的源目录')
    parser.add_argument('backup', help='备份文件存放的目标目录')
    parser.add_argument('--no-compress', action='store_true', 
                       help='不压缩,直接复制备份')
    parser.add_argument('--verbose', '-v', action='store_true',
                       help='显示详细信息')
    args = parser.parse_args()
    # 创建备份工具实例
    backup_tool = BackupTool(
        source_dir=args.source,
        backup_dir=args.backup,
        use_compress=not args.no_compress
    )
    # 执行备份
    backup_path = backup_tool.run()
    if backup_path:
        print(f"\n备份成功完成!")
        print(f"备份文件位置:{backup_path}")
        return 0
    else:
        print("\n备份失败!")
        return 1
if __name__ == "__main__":
    sys.exit(main())

Bash版本(简单实用)

#!/bin/bash
# 简易备份脚本
# 配置
SOURCE_DIR="${1:-/home/user/Documents}"  # 默认源目录
BACKUP_DIR="${2:-/backup}"               # 默认备份目录
KEEP_DAYS=7                              # 保留最近7天的备份
# 获取当前时间戳
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_NAME="backup_${TIMESTAMP}"
LOG_FILE="${BACKUP_DIR}/backup.log"
# 颜色输出
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 日志函数
log_message() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "${LOG_FILE}"
    echo -e "$2"
}
# 检查目录
check_directories() {
    if [ ! -d "$SOURCE_DIR" ]; then
        log_message "错误:源目录不存在: $SOURCE_DIR" "${RED}错误:源目录不存在: $SOURCE_DIR${NC}"
        return 1
    fi
    if [ ! -d "$BACKUP_DIR" ]; then
        log_message "创建备份目录: $BACKUP_DIR" "${YELLOW}创建备份目录: $BACKUP_DIR${NC}"
        mkdir -p "$BACKUP_DIR"
    fi
    return 0
}
# 执行备份(压缩方式)
perform_backup() {
    local source="$1"
    local backup="$2"
    local name="$3"
    log_message "开始备份: $source" "${GREEN}开始备份: $source${NC}"
    # 创建压缩备份
    if tar -czf "${backup}/${name}.tar.gz" -C "$(dirname "$source")" "$(basename "$source")" 2>>"${LOG_FILE}"; then
        local size=$(du -sh "${backup}/${name}.tar.gz" | cut -f1)
        log_message "备份成功: ${backup}/${name}.tar.gz (大小: $size)" 
        echo -e "${GREEN}备份成功: ${backup}/${name}.tar.gz (大小: $size)${NC}"
        return 0
    else
        log_message "备份失败: $source" "${RED}备份失败: $source${NC}"
        return 1
    fi
}
# 清理旧备份
cleanup_old_backups() {
    log_message "清理超过${KEEP_DAYS}天的旧备份..." "${YELLOW}清理超过${KEEP_DAYS}天的旧备份...${NC}"
    # 查找并删除旧的备份文件
    find "$BACKUP_DIR" -name "backup_*.tar.gz" -mtime +${KEEP_DAYS} -delete
    log_message "清理完成" "${GREEN}清理完成${NC}"
}
# 显示使用帮助
show_help() {
    echo "使用方式: $0 [源目录] [备份目录]"
    echo "示例:"
    echo "  $0 /home/user/Documents /mnt/backup"
    echo "  $0 /etc /backup/etc"
}
# 主函数
main() {
    # 显示帮助
    if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
        show_help
        exit 0
    fi
    echo "=========================================="
    echo "        简易备份工具 v1.0"
    echo "=========================================="
    echo "源目录:$SOURCE_DIR"
    echo "备份目录:$BACKUP_DIR"
    echo "=========================================="
    # 检查目录
    if ! check_directories; then
        exit 1
    fi
    # 执行备份
    if perform_backup "$SOURCE_DIR" "$BACKUP_DIR" "$BACKUP_NAME"; then
        # 清理旧备份
        cleanup_old_backups
        echo "=========================================="
        echo -e "${GREEN}备份完成!${NC}"
        echo "备份文件:$BACKUP_DIR/${BACKUP_NAME}.tar.gz"
        echo "备份记录:$LOG_FILE"
        echo "=========================================="
    else
        echo -e "${RED}备份失败!${NC}"
        exit 1
    fi
}
# 运行主函数
main "$@"

使用方法

Python版本:

# 基本使用
python3 backup_tool.py /path/to/source /path/to/backup
# 不压缩直接复制
python3 backup_tool.py /path/to/source /path/to/backup --no-compress
# 显示详细信息
python3 backup_tool.py /path/to/source /path/to/backup -v

Bash版本:

# 基本使用
./backup.sh /path/to/source /path/to/backup
# 显示帮助
./backup.sh --help
# 普通执行
chmod +x backup.sh
./backup.sh /home/user/Documents /mnt/backup

主要功能

  1. 自动时间戳:备份文件自动添加时间戳避免覆盖
  2. 压缩支持:默认使用压缩减少空间占用
  3. 备份记录:记录备份历史,便于追踪
  4. 旧备份清理:自动清理过期的备份文件
  5. 错误处理:包含完整的错误检查和提示
  6. 日志记录:记录备份过程方便排查问题

扩展建议

  1. 添加远程备份支持(rsync、scp等)
  2. 配置定时任务(cron)自动执行
  3. 添加差异备份功能
  4. 支持数据库备份
  5. 添加邮件通知功能
  6. 加密备份文件

这个脚本简单实用,可以根据需要对功能进行扩展和调整!

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