欢迎,来自IP地址为:44.200.122.214 的朋友
Python不仅是一门编程语言,并且还常常被用来完成运维工作。几句简单的脚本,就可以自动完成很多任务。
因为误删而丢失的情况经常发生,定期备份重要文件和文件夹是一种非常有效的方案。但是如果文件较大的话,就需要耗费大量时间成本,为了避免每天重复复制粘贴的无聊操作,可以使用以下Python脚本自动完成。
复制脚本可以根据设置的间隔自动复制指定文件(文件夹),并记录相关日志信息,方便起见将复制脚本命名为”sync.py”。
本示例程序包含如下三个文件:
- Sync.py:主程序,用于完成自动复制
- Sync.ini:配置文件
- Logger.py:日志记录模块
同时,sync.py主程序还会创建一个Sync.log文件用于记录复制日志。主程序示例如下:
import configparser import time import shutil import hashlib from distutils.dir_util import copy_tree from collections import OrderedDict import os import Logger def ConfRead(): config = configparser.ConfigParser() config.read("Sync.ini") return (dict(config.items("Para"))) def md5(fname,size=4096): hash_md5 = hashlib.md5() with open(fname,"rb") as f: for chunk in iter(lambda: f.read(size),b""): hash_md5.update(chunk) return hash_md5.hexdigest() def CopyDir(fromDir,toDir): copy_tree(fromDir,toDir) def CopyFiles(fromFile,path_to_copy): shutil.copy(fromFile,path_to_copy) def OriginalFiles(): drive = All_Config.get("from") Files_Dict = OrderedDict() print(drive) for root,dir,files in os.walk(drive,topdown=True): for file in files: file = file.lower() file_path = root +'\\'+file try: hash_mark = md5(file_path,size=4096) rel_path = file_path.strip(drive) Files_Dict[(hash_mark,rel_path)]= file_path except Exception as e : Logger.logger.error('Error Original files: {0}'.format(e)) return Files_Dict def Destination(): Files_Dict = OrderedDict() _from = All_Config.get("from") _to = All_Config.get("to") _dir = _from.rsplit("\\",)[1] drive = _to+"\\"+_dir print(drive) try: if os.path.isdir(drive): for root,dir,files in os.walk(drive,topdown=True): for file in files: file = file.lower() file_path = root+"\\"+file try: hash_mark = md5(file_path,size=4096) rel_path = file_path.strip(drive) Files_Dict[(hash_mark,rel_path)]=file_path except Exception as e: Logger.logger.error('Error Destination for loop: {0}'.format(e)) return Files_Dict else: CopyDir(_from,drive) Logger.logger.info('Full folder: {0} copied'.format(_from)) return None except Exception as e : Logger.logger.error('Error Destination: {0}'.format(e)) def LogicCompare(): _from = All_Config.get("from") _to = All_Config.get("to") Dest_dict = Destination() if Dest_dict: Source_dict = OriginalFiles() remaining_files = set(Source_dict.keys())- set(Dest_dict.keys()) remaining_files = [Source_dict.get(k) for k in remaining_files] for file_path in remaining_files: try: Logger.logger.info('File: {0}'.format(file_path)) dir, file = file_path.rsplit("\\",1) rel_dir = _from.rsplit("\\",1)[1] rel_dir1 = dir.replace(_from,"") dest_dir = _to if not os.path.isdir(dest_dir): os.makedirs(dest_dir) CopyFiles(file_path, dest_dir) except Exception as e: Logger.logger.error('Error LogicCompare: {0}'.format(e)) if __name__ == '__main__': All_Config = ConfRead() Freq = int(All_Config.get("freq"))*60 Total_time = int(All_Config.get("total_time"))*60 repeat = int(Total_time/Freq) i =1 while True: if i >= repeat: break LogicCompare() time.sleep(Freq) i = i +1
程序首先读取配置文件,然后根据配置内容浏览源文件夹和目标文件夹,并根据文件名进行比较,最后进行复制备份。根据需要,需要文件内容如下:
[Para] From = D:\Test To = D:\Backup Freq = 1 Total_time = 5
程序执行后就会根据设置的时间间隔和频率进行检测和备份,不需要人工干预。日志文件如下所示:
2018-12-25 11:43:03,651-INFO-Full folder: D:\Test copied 2018-12-25 11:43:33,300-INFO-File: D:\Test\test3.bmp 2018-12-25 11:43:33,322-INFO-File: D:\Test\test1.bmp 2018-12-25 11:43:33,347-INFO-File: D:\Test\test2.bmp