如何让文件夹同步函数实现周期性运行并解决参数报错问题?
目录同步脚本问题修复方案
原脚本存在的核心问题
- 定时任务调用
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)
关键修复说明
- 定时任务参数传递:通过
schedule.do()的参数绑定功能,将目录路径和日志路径传入check函数,解决周期同步时缺少参数的报错问题 - 正确的目录对比逻辑:实现递归目录对比函数,替代原脚本中错误的单文件对比方法,准确判断目录是否一致
- 移除冗余删除操作:依赖
robocopy /MIR的镜像同步能力自动处理副本目录的删除,避免手动删除目录引发的异常 - 日志功能优化:封装日志工具函数,使用上下文管理器确保文件资源正确释放,同时添加时间戳提升日志可读性
- 输入容错处理:添加参数数量校验、源目录存在性检查,自动创建不存在的副本目录,避免因输入错误导致脚本崩溃
- 代码可读性提升:重命名模糊的函数和变量,添加清晰注释,降低后期维护成本
内容的提问来源于stack exchange,提问作者Norbert Wieczorek
相关产品推荐
相关产品推荐

