Python实现网站文件的全备份和差异备份

WBOY
Release: 2016-06-10 15:18:42
Original
1206 people have browsed it

之前有写利用md5方式来做差异备份,但是这种md5方式来写存在以下问题:

•md5sum获取有些软连接的MD5值存在问题
•不支持对空目录进行备份,因为md5sum无法获取空目录的md5值
•权限的修改md5sum无法判断

解决方案:

利用文件的mtime ctime

mtime(Modified time)是在写入文件时随文件内容的更改而更改的
ctime(Create time)是在写入文件、更改所有者、权限或链接设置时随Inode的内容更改而更改的
废话不多说直接上代码:

#!/usr/bin/env python
import time,os,sys,cPickle

fileInfo = {}

def logger(time,fileName,status,fileNum):
  f = open('backup.log','a')
  f.write("%s\t%s\t%s\t\t%s\n" % (time,fileName,status,fileNum))

def tar(sDir,dDir,fileNum):
  command = "tar zcf %s %s >/dev/null 2>&1" % (dDir + ".tar.gz",sDir)
  if os.system(command) == 0:
    logger(time.strftime('%F %X'),dDir + ".tar.gz",'success',fileNum)
  else:
    logger(time.strftime('%F %X'),dDir + ".tar.gz",'failed',fileNum)

def fullBak(path):
  fileNum = 0
  for root,dirs,files in os.walk(path):
    for name in files:
      file = os.path.join(root, name)
      mtime = os.path.getmtime(file)
      ctime = os.path.getctime(file)
      fileInfo[file] = (mtime,ctime)
      fileNum += 1
  f = open(P,'w')
  cPickle.dump(fileInfo,f)
  f.close()
  tar(S,D,fileNum)

def diffBak(path):
  for root,dirs,files in os.walk(path):
    for name in files:
      file = os.path.join(root,name)
      mtime = os.path.getmtime(file)
      ctime = os.path.getctime(file)
      fileInfo[file] = (mtime,ctime)

  if os.path.isfile(P) == 0:
    f = open(P,'w')
    f.close()

  if os.stat(P).st_size == 0:
    f = open(P,'w')
    cPickle.dump(fileInfo,f)
    fileNum = len(fileInfo.keys())
    f.close()
    print fileNum
    tar(S,D,fileNum)
  else:
    f = open(P)
    old_fileInfo = cPickle.load(f)
    f.close()
    difference = dict(set(fileInfo.items())^set(old_fileInfo.items()))
    fileNum = len(difference)
    print fileNum

    difference_file = ' '.join(difference.keys())
    print difference_file

    tar(difference_file,D,fileNum)
    f = open(P,'w')
    cPickle.dump(fileInfo,f)
    f.close()

def Usage():
  print '''
    Syntax: python file_bakcup.py pickle_file model source_dir filename_bk
      model: 1:Full backup 2:Differential backup

    example: python file_backup.py fileinfo.pk 2 /etc etc_$(date +%F)
      explain: Automatically add '.tar.gz' suffix
  '''
  sys.exit()

if len(sys.argv) != 5:
  Usage()

P = sys.argv[1]
M = int(sys.argv[2])
S = sys.argv[3]
D = sys.argv[4]

if M == 1:
  fullBak(S)
elif M == 2:
  diffBak(S)
else:
  print "\033[;31mDoes not support this mode\033[0m"
  Usage()
Copy after login

测试:

$ python file_backup.py data.pk 1 data data_$(date +%F) #全备份
$ > data/www.jb51.net #测试创建文件,修改文件权限
$ chmod 777 data/py/eshop_bk/data.db
$ python file_backup.py data.pk 2 data data_$(date +%F)_1 #备份改变的文件
2
data/py/eshop_bk/data.db data/www.jb51.net
Copy after login

看了博主的代码,很受启发,但是有一个问题,如果我完成完整备份之后,删除了其中某个文件,再做差异备份,可以检测出被删除的文件,但是执行tar就会出错,因为这个文件已经是不存在的了,所以在执行tar之前,最好用os.path.exists()判断一下差异文件路径是否存在,如果不存在则不执行tar, 反馈一条文件删除信息。

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!