脚本如何实现文件夹同步功能

wen 实用脚本 1

本文目录导读:

脚本如何实现文件夹同步功能

  1. Python 实现(推荐)
  2. rsync 脚本 (Linux/Mac)
  3. PowerShell 脚本 (Windows)
  4. 使用 PyInotify (Linux 实时同步)
  5. 使用建议
  6. 安装依赖

Python 实现(推荐)

基本双向同步

import os
import shutil
import filecmp
from datetime import datetime
def sync_folders(src_dir, dst_dir, sync_type='one_way'):
    """
    文件夹同步功能
    sync_type: 'one_way' 单向同步 (src -> dst)
               'two_way' 双向同步
    """
    if not os.path.exists(dst_dir):
        os.makedirs(dst_dir)
    # 获取源目录文件列表
    for root, dirs, files in os.walk(src_dir):
        # 计算相对路径
        rel_path = os.path.relpath(root, src_dir)
        dst_root = os.path.join(dst_dir, rel_path)
        # 创建目标子目录
        if not os.path.exists(dst_root):
            os.makedirs(dst_root)
        # 同步文件
        for file in files:
            src_file = os.path.join(root, file)
            dst_file = os.path.join(dst_root, file)
            # 检查是否需要同步
            if not os.path.exists(dst_file) or \
               os.path.getmtime(src_file) > os.path.getmtime(dst_file):
                shutil.copy2(src_file, dst_file)
                print(f"已同步: {src_file} -> {dst_file}")
    # 如果是双向同步
    if sync_type == 'two_way':
        # 反向同步
        for root, dirs, files in os.walk(dst_dir):
            rel_path = os.path.relpath(root, dst_dir)
            src_root = os.path.join(src_dir, rel_path)
            for file in files:
                dst_file = os.path.join(root, file)
                src_file = os.path.join(src_root, file)
                if not os.path.exists(src_file) or \
                   os.path.getmtime(dst_file) > os.path.getmtime(src_file):
                    if not os.path.exists(src_root):
                        os.makedirs(src_root)
                    shutil.copy2(dst_file, src_file)
                    print(f"已同步: {dst_file} -> {src_file}")
# 使用示例
sync_folders('/path/to/source', '/path/to/destination')

带监控的实时同步

import time
import hashlib
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
class SyncHandler(FileSystemEventHandler):
    def __init__(self, src_dir, dst_dir):
        self.src_dir = src_dir
        self.dst_dir = dst_dir
        self.last_modified = {}
    def should_sync(self, file_path):
        """检查文件是否真的需要同步"""
        current_mtime = os.path.getmtime(file_path)
        file_hash = hashlib.md5(open(file_path, 'rb').read()).hexdigest()
        if file_path in self.last_modified:
            if self.last_modified[file_path] == file_hash:
                return False
        self.last_modified[file_path] = file_hash
        return True
    def on_modified(self, event):
        if event.is_directory:
            return
        file_path = event.src_path
        if not self.should_sync(file_path):
            return
        # 计算相对路径
        rel_path = os.path.relpath(file_path, self.src_dir)
        dst_path = os.path.join(self.dst_dir, rel_path)
        # 确保目标目录存在
        os.makedirs(os.path.dirname(dst_path), exist_ok=True)
        # 复制文件
        shutil.copy2(file_path, dst_path)
        print(f"实时同步: {file_path} -> {dst_path}")
def real_time_sync(src_dir, dst_dir):
    """实时文件夹同步"""
    event_handler = SyncHandler(src_dir, dst_dir)
    observer = Observer()
    observer.schedule(event_handler, src_dir, recursive=True)
    observer.start()
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()
# 需要安装: pip install watchdog
# real_time_sync('/path/to/source', '/path/to/destination')

rsync 脚本 (Linux/Mac)

#!/bin/bash
# sync_folders.sh - 文件夹同步脚本
SOURCE_DIR="$1"
DEST_DIR="$2"
LOG_FILE="/var/log/folder_sync.log"
# 检查参数
if [ $# -lt 2 ]; then
    echo "使用方法: $0 <源目录> <目标目录>"
    exit 1
fi
# 同步功能
sync_folders() {
    local src="$1"
    local dst="$2"
    echo "[$(date)] 开始同步: $src -> $dst" >> "$LOG_FILE"
    # 使用 rsync 进行同步
    rsync -avz --delete \
        --progress \
        --exclude=".DS_Store" \
        --exclude="Thumbs.db" \
        --exclude="node_modules/" \
        --exclude=".git/" \
        "$src/" "$dst/" 2>&1 | tee -a "$LOG_FILE"
    echo "[$(date)] 同步完成" >> "$LOG_FILE"
}
# 执行同步
sync_folders "$SOURCE_DIR" "$DEST_DIR"

PowerShell 脚本 (Windows)

# sync_folders.ps1 - Windows文件夹同步脚本
param(
    [Parameter(Mandatory=$true)]
    [string]$Source,
    [Parameter(Mandatory=$true)]
    [string]$Destination,
    [switch]$TwoWay,
    [switch]$Log
)
function Sync-Folder {
    param(
        [string]$src,
        [string]$dst,
        [string]$direction
    )
    $logMessage = "[$(Get-Date)] 开始同步 $direction: $src -> $dst"
    Write-Host $logMessage
    # 使用 Robocopy 进行同步
    $robocopyArgs = @(
        $src,
        $dst,
        "/MIR",           # 镜像模式
        "/R:3",           # 重试次数
        "/W:5",           # 等待时间
        "/NP",            # 不显示进度
        "/NJH",           # 不显示作业头
        "/NJS"            # 不显示作业摘要
    )
    if ($Log) {
        $robocopyArgs += "/LOG+:sync_log.txt"
    }
    robocopy @robocopyArgs
    # 双向同步
    if ($TwoWay -and $direction -eq "源->目标") {
        Sync-Folder -src $dst -dst $src -direction "目标->源"
    }
}
# 执行同步
Sync-Folder -src $Source -dst $Destination -direction "源->目标"

使用 PyInotify (Linux 实时同步)

import pyinotify
import os
import shutil
class SyncWatcher(pyinotify.ProcessEvent):
    def __init__(self, src_dir, dst_dir):
        self.src_dir = src_dir
        self.dst_dir = dst_dir
    def process_IN_CREATE(self, event):
        """文件创建时同步"""
        self.sync_file(event.pathname)
    def process_IN_MODIFY(self, event):
        """文件修改时同步"""
        self.sync_file(event.pathname)
    def process_IN_DELETE(self, event):
        """文件删除时同步"""
        rel_path = os.path.relpath(event.pathname, self.src_dir)
        dst_path = os.path.join(self.dst_dir, rel_path)
        if os.path.exists(dst_path):
            os.remove(dst_path)
    def sync_file(self, src_path):
        rel_path = os.path.relpath(src_path, self.src_dir)
        dst_path = os.path.join(self.dst_dir, rel_path)
        os.makedirs(os.path.dirname(dst_path), exist_ok=True)
        shutil.copy2(src_path, dst_path)
        print(f"已同步: {src_path}")
def start_watcher(src_dir, dst_dir):
    wm = pyinotify.WatchManager()
    mask = pyinotify.IN_CREATE | pyinotify.IN_MODIFY | pyinotify.IN_DELETE
    handler = SyncWatcher(src_dir, dst_dir)
    notifier = pyinotify.Notifier(wm, handler)
    wm.add_watch(src_dir, mask, rec=True, auto_add=True)
    notifier.loop()
# 需要安装: pip install pyinotify
# start_watcher('/path/to/source', '/path/to/destination')

使用建议

场景 推荐方案 理由
一次性同步 rsync/Python 简单高效
实时同步 watchdog/PyInotify 自动监控变化
Windows环境 PowerShell 原生支持
跨平台 Python 兼容性好
大文件同步 rsync 支持增量传输

安装依赖

# Python依赖
pip install watchdog  # 实时监控
pip install pyinotify  # Linux实时监控
# Linux工具
sudo apt-get install rsync  # Ubuntu/Debian
sudo yum install rsync      # CentOS/RHEL

选择适合你需求的方案,建议先用基本版本测试,再根据需要进行扩展。

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