Python使用filecmp校验源目录备份目录

确认备份目录与源目录文件是否保持一致,包括源目录中的新文件或目录、删除文件或删除目录、更新文件或目录有无成功同步,定期校验,保证源目录和备份目录的同步,对相同文件不做任何改动,对更新文件或目录、新文件或目录进行拷贝更新,对源目录删除文件或目录在备份目录中删除

使用filecmp模块的left_only,diff_files等获取更新项目,right_only获取源目录中删除项

使用命令find dir1 -type f -print0 | xargs -0 md5sum快捷目录清单对比
Python使用filecmp校验源目录备份目录_第1张图片

#!/usr/bin/env python3
#
import filecmp
import os, sys
import re
import shutil
update_files = []
update_dirs = []
delete_files = []
delete_dirs = []

def compare(source, backup):                        # 递归获取更新项目函数
    uplist = []
    dellist = []
    dircomp = filecmp.dircmp(source, backup)
    only_in_left = dircomp.left_only            # 源目录新文件或目录
    only_in_right = dircomp.right_only          # 源目录删除了的文件
    diff_in_one = dircomp.diff_files            # 不匹配的文件,源目录文件发生修改
    dirpath = os.path.abspath(source)
    [update_files.append(os.path.abspath(os.path.join(source, x))) for x in only_in_left \
        if os.path.isfile(os.path.abspath(os.path.join(source, x)))]
    [update_files.append(os.path.abspath(os.path.join(source, x))) for x in diff_in_one \
        if os.path.isfile(os.path.abspath(os.path.join(source, x)))]
    [delete_files.append(os.path.abspath(os.path.join(backup, x))) for x in only_in_right \
        if os.path.isfile(os.path.abspath(os.path.join(backup, x)))]
    [uplist.append(os.path.abspath(os.path.join(source, x))) for x in only_in_left \
        if os.path.isdir(os.path.abspath(os.path.join(source, x)))]
    [dellist.append(os.path.abspath(os.path.join(backup, x))) for x in only_in_right \
        if os.path.isdir(os.path.abspath(os.path.join(backup, x)))]
    if len(dircomp.common_dirs) > 0:
        for item in dircomp.common_dirs:
            compare(os.path.abspath(os.path.join(source, item)), \
                os.path.abspath(os.path.join(backup, item)))
    if len(uplist) > 0:
        for item in uplist:
            getdir(item, source, backup)
            update_dirs.append(re.sub(source, backup, item))
    if len(dellist) > 0:
        for item in dellist:
            delete_dirs.append(item)
    result = {
    "updatefiles":update_files,"updatedirs":update_dirs,"deletefiles":delete_files,"deletedirs":delete_dirs}
    return result

def getdir(path, source, backup):
    dirpath = os.path.abspath(path)
    temp = os.listdir(path)
    dirs = []
    [update_files.append(os.path.abspath(os.path.join(source, x))) for x in temp \
        if os.path.isfile(os.path.abspath(os.path.join(path, x)))]
    [dirs.append(os.path.abspath(os.path.join(path, x))) for x in temp \
        if os.path.isdir(os.path.abspath(os.path.join(path, x)))]
    for item in dirs:
        update_dirs.append(re.sub(source, backup, item))
        getdir(item, source, backup)

def update(source, backup, updatefiles, updatedirs):
    source_path = os.path.abspath(source)
    print("begin create new directories...")
    for item in updatedirs:
        os.makedirs(item)
    print("begin update files...")
    for item in updatefiles:
        backfile = re.sub(source, backup, item)
        shutil.copyfile(item, backfile)


def delete(deletefiles, deletedirs):
    print("begin to delete file...")
    for item in deletefiles:
        os.remove(item)
    print("begin to delete directories...")
    for item in deletedirs:
        shutil.rmtree(item) 
    pass

def main():
    if len(sys.argv) > 2:
        dir1 = sys.argv[1]
        dir2 = sys.argv[2]
        if not dir1.endswith("/"): dir1 = dir1 + "/"
        if not dir2.endswith("/"): dir2 = dir2 + "/"
    else:
        print("Usage: " + sys.argv[0] + "datadir backupdir")
        sys.exit()
    result = compare(dir1, dir2)
    updatefiles = result["updatefiles"]
    updatedirs = result["updatedirs"]
    deletefiles = result["deletefiles"]
    deletedirs = result["deletedirs"]
    delete(deletefiles, deletedirs)
    update(dir1, dir2, updatefiles, updatedirs)
    print("Files need to update:" + str(updatefiles))
    print("directory need to create:" + str(updatedirs))
    print("Files need to delete:" + str(deletefiles))
    print("directory need to delete:" + str(deletedirs))

if __name__ == "__main__":
    main()

执行脚本之后
Python使用filecmp校验源目录备份目录_第2张图片

你可能感兴趣的:(Python运维,Linux,python,备份,filecmp)