Python supports full backup and differential backup of website files,
Previously, the md5 mode was used for differential backup, but the md5 mode has the following problems:
• An error occurred while obtaining the MD5 value of some soft connections by using md5sum.
• Empty directories cannot be backed up because md5sum cannot obtain the md5 value of an empty directory.
• Permission modification md5sum cannot be judged
Solution:
Use the mtime ctime of the file
Mtime (Modified time) is changed as the file content changes when the file is written.
Ctime (Create time) is changed as Inode content changes when the file is written, the owner, permission, or link settings are changed.
Let's talk a little bit about the Code:
#!/usr/bin/env pythonimport time,os,sys,cPicklefileInfo = {}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()
Test:
$ Python file_backup.py data. pk 1 data _ $ (date + % F) # Full backup $> data/www.jb51.net # Test File Creation and modify file permissions $ chmod 777 data/py/eshop_bk/data. db $ python file_backup.py data. pk 2 data _ $ (date + % F) _ 1 # back up the changed file 2 data/py/eshop_bk/data. db data/www.jb51.net
I was inspired to read the blogger's code, but there is a problem. If I delete a file after completing the full backup and perform differential backup, I can detect the deleted file, but an error occurs when you execute tar. Because this file does not exist, you are advised to use OS before executing tar. path. exists () checks whether the path of the differential file exists. If the path does not exist, the tar command is not executed, and a file deletion information is returned.