本文目录导读:

我来提供一个功能完整但实现简单的备份工具脚本,这里提供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
主要功能
- 自动时间戳:备份文件自动添加时间戳避免覆盖
- 压缩支持:默认使用压缩减少空间占用
- 备份记录:记录备份历史,便于追踪
- 旧备份清理:自动清理过期的备份文件
- 错误处理:包含完整的错误检查和提示
- 日志记录:记录备份过程方便排查问题
扩展建议
- 添加远程备份支持(rsync、scp等)
- 配置定时任务(cron)自动执行
- 添加差异备份功能
- 支持数据库备份
- 添加邮件通知功能
- 加密备份文件
这个脚本简单实用,可以根据需要对功能进行扩展和调整!