如何编写文件夹同步脚本

wen 实用脚本 29

本文目录导读:

如何编写文件夹同步脚本

  1. 使用 rsync(Linux/macOS)
  2. 使用 robocopy(Windows)
  3. Python 脚本(跨平台)
  4. 定时任务配置
  5. 实用技巧
  6. 使用建议

使用 rsync(Linux/macOS)

#!/bin/bash
# sync_folders.sh
SOURCE="/path/to/source/"
DESTINATION="/path/to/destination/"
# 基本同步
rsync -avz --delete "$SOURCE" "$DESTINATION"
# 带日志的同步
rsync -avz --delete "$SOURCE" "$DESTINATION" --log-file="sync.log"
# 排除特定文件
rsync -avz --delete --exclude="*.tmp" --exclude="cache/" "$SOURCE" "$DESTINATION"

使用 robocopy(Windows)

@echo off
REM sync_folders.bat
set SOURCE=C:\path\to\source\
set DESTINATION=D:\path\to\destination\
REM 基本同步
robocopy %SOURCE% %DESTINATION% /E /COPYALL /R:3 /W:10
REM 镜像同步(删除目标多余文件)
robocopy %SOURCE% %DESTINATION% /MIR /R:3 /W:10
REM 带日志的同步
robocopy %SOURCE% %DESTINATION% /E /COPYALL /R:3 /W:10 /LOG+:sync.log

Python 脚本(跨平台)

#!/usr/bin/env python3
# sync_folders.py
import os
import shutil
import hashlib
from pathlib import Path
import argparse
class FolderSync:
    def __init__(self, source, destination, dry_run=False):
        self.source = Path(source)
        self.destination = Path(destination)
        self.dry_run = dry_run
    def get_file_hash(self, filepath):
        """计算文件哈希值"""
        hasher = hashlib.md5()
        with open(filepath, 'rb') as f:
            buf = f.read(65536)
            while len(buf) > 0:
                hasher.update(buf)
                buf = f.read(65536)
        return hasher.hexdigest()
    def sync(self):
        """执行同步"""
        if not self.source.exists():
            print(f"源文件夹不存在: {self.source}")
            return
        if not self.destination.exists():
            if not self.dry_run:
                self.destination.mkdir(parents=True)
            print(f"创建目标文件夹: {self.destination}")
        # 同步文件
        for root, dirs, files in os.walk(self.source):
            relative_path = Path(root).relative_to(self.source)
            target_dir = self.destination / relative_path
            # 创建目标子文件夹
            if not target_dir.exists():
                if not self.dry_run:
                    target_dir.mkdir(parents=True)
                print(f"创建文件夹: {target_dir}")
            # 同步文件
            for file in files:
                source_file = Path(root) / file
                target_file = target_dir / file
                # 复制新文件或更新文件
                if not target_file.exists() or \
                   self.get_file_hash(source_file) != self.get_file_hash(target_file):
                    if not self.dry_run:
                        shutil.copy2(source_file, target_file)
                    print(f"复制: {source_file} -> {target_file}")
        # 删除目标中多余的文件
        for root, dirs, files in os.walk(self.destination):
            relative_path = Path(root).relative_to(self.destination)
            source_dir = self.source / relative_path
            if not source_dir.exists():
                if not self.dry_run:
                    shutil.rmtree(root)
                print(f"删除文件夹: {root}")
                continue
            for file in files:
                target_file = Path(root) / file
                source_file = source_dir / file
                if not source_file.exists():
                    if not self.dry_run:
                        target_file.unlink()
                    print(f"删除文件: {target_file}")
def main():
    parser = argparse.ArgumentParser(description='文件夹同步脚本')
    parser.add_argument('source', help='源文件夹路径')
    parser.add_argument('destination', help='目标文件夹路径')
    parser.add_argument('--dry-run', action='store_true', 
                       help='预览模式,不实际执行操作')
    args = parser.parse_args()
    syncer = FolderSync(args.source, args.destination, args.dry_run)
    syncer.sync()
if __name__ == "__main__":
    main()

定时任务配置

Linux crontab(每天凌晨2点执行)

# 编辑 crontab
crontab -e
# 添加定时任务
0 2 * * * /path/to/sync_folders.sh
# 或者使用详细的 rsync 命令
0 2 * * * rsync -avz --delete /source/ /destination/ >> /var/log/sync.log 2>&1

Windows 任务计划程序

# 创建定时任务(PowerShell)
$action = New-ScheduledTaskAction -Execute "powershell.exe" `
    -Argument "-File C:\path\to\sync_folders.ps1"
$trigger = New-ScheduledTaskTrigger -Daily -At "02:00AM"
Register-ScheduledTask -TaskName "FolderSync" `
    -Action $action `
    -Trigger $trigger `
    -RunLevel Highest

实用技巧

实时同步(使用 inotify)

#!/bin/bash
# 使用 inotifywait 进行实时同步
SOURCE="/path/to/source"
DESTINATION="/path/to/destination"
inotifywait -m -r -e modify,create,delete,move "$SOURCE" --format '%e %w%f' |
while read event file; do
    rsync -avz --delete "$SOURCE/" "$DESTINATION/"
    echo "$(date): 同步完成 - $event: $file"
done

双向同步示例

#!/bin/bash
# bidirectional_sync.sh
FOLDER1="/path/to/folder1"
FOLDER2="/path/to/folder2"
LOCKFILE="/tmp/sync.lock"
if [ -f "$LOCKFILE" ]; then
    echo "同步正在进行中..."
    exit 1
fi
touch "$LOCKFILE"
# 同步 FOLDER1 -> FOLDER2
rsync -avz --delete "$FOLDER1/" "$FOLDER2/"
# 同步 FOLDER2 -> FOLDER1(排除已经同步的文件)
rsync -avz --delete "$FOLDER2/" "$FOLDER1/" --exclude-from="/tmp/sync_exclude"
rm "$LOCKFILE"

使用建议

  1. 先在测试环境试用:使用 --dry-run--what-if 参数预览
  2. 做好备份:第一次同步前备份重要数据
  3. 添加错误处理:检查磁盘空间、网络连接等
  4. 记录日志:便于排查问题
  5. 添加通知:通过邮件或消息通知同步状态

根据你的具体需求选择合适的方法,需要更多帮助请告诉我!

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