找回密码
  注册[Register]
查看: 643|回复: 6

[python] python文件自动同步备份v1【运维必备】

  [复制链接]
发表于 2020-12-25 21:22 | 显示全部楼层 |阅读模式
禁止求评分、诱导评分、互刷评分、互刷悬赏值,违规者封号处理。
禁止发布推广、邀请码、邀请链接、二维码或者有利益相关的任何推广行为。
所有非原创软件请发布在【精品软件区】,发帖必须按照本版块版规格式发帖。

先说需求:平台会把虚拟机备份的文件打包到服务器A,再同步备份到服务器B(只需要考虑A到B)。


思路:
服务器A作为服务端,定时遍历自己的文件目录,把文件目录信息打包成一个校验文件。
服务器B作为客户端,下载校验文件,遍历自己的文件目录是否和服务器相同,并下载本地没有的文件。
通过http传输,使用python开启一个简单的http服务。


测试环境:
win10→CentOS7, python3.7。


首先开启Http服务:
在win10上找到需要备份的文件夹,在空白处shift+鼠标右键,点击在此处打开powershell窗口。
然后输入:
  1. python -m http.server 8000
复制代码




开启后访问http://本机Ip:8000即可

服务端代码如下:
  1. import os

  2. path = r'C:\Users\001\Desktop\backup'
  3. def content(path):
  4.     list = []
  5.     dir = []
  6.     x = os.walk(path, topdown=True)
  7.     for (root, dirs, files) in x:
  8.         dir.append(root.replace(r'C:\Users\001\Desktop\backup', ''))
  9.         for j in files:
  10.             list.append(root.replace(r'C:\Users\001\Desktop\backup', '') + '\\' + j)
  11.     return [dir, list]

  12. x = content(path)

  13. with open(path+'\\'+'init.txt', 'w', encoding='utf-8') as f:
  14.     for i in x[1]:
  15.         f.write(i)
  16.         f.write('\n')

  17. with open(path+'\\'+'dir.txt', 'w', encoding='utf-8') as f:
  18.     for i in x[0]:
  19.         f.write(i)
  20.         f.write('\n')
复制代码



客户端代码如下:
  1. import os
  2. import requests
  3. import shutil
  4. import time
  5. from tqdm import tqdm

  6. start_time = time.perf_counter()

  7. def init():
  8.     # 下载服务端目录,文件信息
  9.     url = ['http://192.168.1.13:8000/init.txt', 'http://192.168.1.13:8000/dir.txt']

  10.     download_init = requests.get(url[0], stream=True)
  11.     with open('/download/init.txt', 'wb') as f:
  12.         for chunk in download_init.iter_content(chunk_size=1024):
  13.             f.write(chunk)

  14.     download_dir = requests.get(url[1], stream=True)
  15.     with open('/download/dir.txt', 'wb') as f:
  16.         for chunk in tqdm(download_dir.iter_content(chunk_size=1024)):
  17.             f.write(chunk)

  18. init()

  19. path = '/download/backup'

  20. def content(path):
  21.     list = []
  22.     dir = []
  23.     x = os.walk(path, topdown=True)
  24.     for (root, dirs, files) in x:
  25.         dir.append(root)
  26.         for j in files:
  27.             list.append(root+ '/' + j)
  28.     return [dir, list]


  29. def check_dir():
  30.     # 获取本地目录
  31.     x = content(path)
  32.     dir_so = x[0]

  33.     # 清洗服务端目录
  34.     dirs = open('/download/dir.txt', 'r', encoding='utf-8')
  35.     dir_dst = dirs.readlines()
  36.     dir_dst_info = []
  37.     for i in dir_dst:
  38.         i = i.replace('\n', '')
  39.         i = i.replace('\\', '/')
  40.         i = '/download/backup' + i # 修改路径不然会报错
  41.         dir_dst_info.append(i)


  42.     # 比较目录,目录不一致就添加
  43.     for i in dir_dst_info[1:]+dir_so:
  44.         if i not in dir_so:
  45.             os.mkdir(i)
  46.             print('创建了' + i)
  47.         if i not in dir_dst_info:
  48.             try:
  49.                 shutil.rmtree(i)
  50.                 print('删除了' + i)
  51.             except:
  52.                 pass


  53. check_dir()

  54. def check_file():
  55.     # 获取本地文件
  56.     x = content(path)
  57.     file_so = x[1]

  58.     # 清洗服务端文件
  59.     files = open('/download/init.txt', 'r', encoding='utf-8')
  60.     files_dst = files.readlines()
  61.     files_dst_info = []
  62.     for i in files_dst:
  63.         i = i.replace('\n', '')
  64.         i = i.replace('\\', '/')
  65.         files_dst_info.append('/download/backup' + i)

  66.     # 没有的下载,多余的删掉
  67.     for i in file_so + files_dst_info:
  68.         if i not in file_so:
  69.             url = 'http://192.168.1.13:8000' + i.replace('/download/backup', '')
  70.             download_file = requests.get(url, stream=True)
  71.             with open(i, 'wb') as f :
  72.                 for chunk in download_file.iter_content(chunk_size=10240) :
  73.                     f.write(chunk)
  74.                     print('添加了' + i)
  75.         if i not in files_dst_info:
  76.             os.remove(i)
  77.             print('删除了' + i)

  78. check_file()

  79. end_time =time.perf_counter()

  80. cost = end_time - start_time
  81. print(cost,':s')
复制代码



代码还在优化,目前的功能有:
1、可以添加定时任务,做到同步更新。
2、支持同步删除。
待开发的功能:
1、多线程/多进程下载。
还没有投入到生产环境中正式测试,测试图片先欠着,代码调优完了再来改。

如果有更好的建议欢迎各位指教。
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心值】和【牛币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
发表于 2020-12-25 21:22 | 显示全部楼层
多谢楼主分享
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心值】和【牛币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 有用 没用

使用道具 举报

发表于 2020-12-25 21:49 | 显示全部楼层
6666
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心值】和【牛币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 有用 没用

使用道具 举报

发表于 2020-12-25 23:22 | 显示全部楼层

感谢分享,谢谢提供分享
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心值】和【牛币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 有用 没用

使用道具 举报

发表于 2020-12-25 23:24 | 显示全部楼层

感谢楼主的分享
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心值】和【牛币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 有用 没用

使用道具 举报

发表于 2020-12-26 07:34 | 显示全部楼层
谢谢分享!
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心值】和【牛币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 有用 没用

使用道具 举报

发表于 2020-12-26 08:36 | 显示全部楼层
多谢分享多谢分享
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心值】和【牛币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 有用 没用

使用道具 举报

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

RSS订阅|手机版|小黑屋|大牛论坛 |我的广告

GMT+8, 2024-5-3 10:53 , Processed in 0.044115 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表