You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让文件夹同步函数实现周期性运行并解决参数报错问题?

目录同步脚本问题修复方案

原脚本存在的核心问题

  • 定时任务调用check函数时未传递参数,导致执行周期同步时因缺少path1/path2/path3报错
  • 误用filecmp.cmp()比较文件夹,该函数仅适用于单个文件对比
  • 删除副本目录内容时,尝试用os.remove()删除目录,会抛出异常
  • 冗余的手动删除逻辑:robocopy /MIR本身已实现镜像同步(自动删除副本中源目录不存在的内容)
  • 日志文件重复打开,存在资源泄漏风险
  • 缺少参数合法性校验,传参错误时直接崩溃

修复后的完整代码

from subprocess import call
import sys
import os
import filecmp
import schedule
import time


def check(source_path, replica_path, log_path):
    # 写入日志的工具函数,避免重复打开文件
    def log(message):
        with open(log_path, 'a', encoding='utf-8') as f:
            print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] {message}", file=f)
        print(message)  # 同时输出到控制台

    # 递归对比两个目录是否完全一致
    def are_dirs_equal(dir1, dir2):
        dir_cmp = filecmp.dircmp(dir1, dir2)
        # 存在单侧独有文件/目录、差异文件,则判定不一致
        if dir_cmp.left_only or dir_cmp.right_only or dir_cmp.diff_files:
            return False
        # 递归检查子目录
        for sub_dir in dir_cmp.common_dirs:
            if not are_dirs_equal(os.path.join(dir1, sub_dir), os.path.join(dir2, sub_dir)):
                return False
        return True

    try:
        if are_dirs_equal(source_path, replica_path):
            log("源目录与副本目录内容完全一致,无需同步")
            return

        log(f"开始同步:源目录 {source_path} → 副本目录 {replica_path}")
        # 使用robocopy /MIR实现镜像同步,自动处理新增、修改、删除
        # /NFL /NDL 不记录文件/目录列表,/NP 不显示进度,简化输出
        call(["robocopy", source_path, replica_path, "/MIR", "/NFL", "/NDL", "/NP"])
        log("同步完成,源目录与副本目录已保持一致")
    except Exception as e:
        log(f"同步过程中出现错误:{str(e)}")


def start_scheduler(interval, source_path, replica_path, log_path):
    # 给定时任务绑定所需参数
    schedule.every(int(interval)).minutes.do(
        check,
        source_path=source_path,
        replica_path=replica_path,
        log_path=log_path
    )
    print(f"已启动定时同步任务,周期:{interval}分钟")
    while True:
        schedule.run_pending()
        time.sleep(1)


if __name__ == "__main__":
    # 参数合法性校验
    if len(sys.argv) != 6 or sys.argv[1] != "-c":
        print("使用方式:python sync_script.py -c <源目录路径> <副本目录路径> <同步周期(分钟)> <日志文件路径>")
        sys.exit(1)

    source = sys.argv[2]
    replica = sys.argv[3]
    interval = sys.argv[4]
    log_file = sys.argv[5]

    # 检查源目录是否存在
    if not os.path.isdir(source):
        print(f"错误:源目录 {source} 不存在")
        sys.exit(1)
    # 自动创建副本目录(如果不存在)
    os.makedirs(replica, exist_ok=True)

    # 先执行一次立即同步
    check(source, replica, log_file)
    # 启动定时任务
    start_scheduler(interval, source, replica, log_file)

关键修复说明

  1. 定时任务参数传递:通过schedule.do()的参数绑定功能,将目录路径和日志路径传入check函数,解决周期同步时缺少参数的报错问题
  2. 正确的目录对比逻辑:实现递归目录对比函数,替代原脚本中错误的单文件对比方法,准确判断目录是否一致
  3. 移除冗余删除操作:依赖robocopy /MIR的镜像同步能力自动处理副本目录的删除,避免手动删除目录引发的异常
  4. 日志功能优化:封装日志工具函数,使用上下文管理器确保文件资源正确释放,同时添加时间戳提升日志可读性
  5. 输入容错处理:添加参数数量校验、源目录存在性检查,自动创建不存在的副本目录,避免因输入错误导致脚本崩溃
  6. 代码可读性提升:重命名模糊的函数和变量,添加清晰注释,降低后期维护成本

内容的提问来源于stack exchange,提问作者Norbert Wieczorek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 14:05:30