公司有一台静态页面展现服务器仅供给客户展现咱们作的项目,当时买的时候是最低配,也就是磁盘空间为20G的系统盘,考虑到代码量很小因此没有另加磁盘,后来项目多了,就写了个crontab 定时备份目录。html
就这样,这台服务器稳健运行着。过了大半年,忽然有一天挂在该服务器上的wordpress登录不了了。找了很久找不到问题。不经意之间看来下磁盘利用率才发现了问题。python
使用命令:linux
df -h
发现磁盘/dev/xvdal没空间了!windows
致使缓存与session没法保存。想起来多是备份目录致使的,10几个项目,一个项目10Mb左右天天备份一次,半年时间:10*10*150=15GB(项目是逐渐加进去的),删除某一天的备份,从新登陆wordpress真给登陆上去了。缓存
若是知道了是备份的问题,按期删除备份文件也行。但爱折腾的人确定是闲不下来的。干吗要备份到服务器中呢,彻底能够打包把备份文件经过邮件进行备份呀。就这样定时Python备份目录发送邮件功能变成了“现实”。服务器
crontab -e
30 1 * * * /root/crontab-save-code.py #天天凌晨1点30分执行备份目录
# 压缩目录toZip def DirToZip(dirname, zipfilename): filelist = [] if os.path.isfile(dirname): filelist.append(dirname) else: for root, dirs, files in os.walk(dirname): for name in files: filelist.append(os.path.join(root, name)) try: zf = zipfile.ZipFile(zipfilename, "w", zipfile.zlib.DEFLATED) for tar in filelist: arcname = tar[len(dirname):] try: # 异常出如今文件名为中文 zf.write(tar, arcname) except: zf.write(tar, repr(arcname)[1:-1]) zf.close() return True except Exception as e: return False
生成ZIP压缩文件时有个问题,压缩到一半报错:session
'utf-8' codec can't encode character '\udcb8' in position 41: surrogates not allowed
编码的问题,文件使用中文名致使的,参考: http://python3-cookbook.readthedocs.io/zh_CN/latest/c05/p15_printing_bad_filenames.htmlapp
# 发送邮件 def sendMail(): print(ZipName) # 输入Email地址和口令: from_addr = 'admin@****.com' password = '123456' # 输入收件人地址: to_addr = '*****@163.com' # 输入SMTP服务器地址: smtp_server = 'smtp.exmail.qq.com' # 邮件对象: msg = MIMEMultipart() msg['From'] = _format_addr('自动备份项目代码 <%s>' % from_addr) msg['To'] = _format_addr('Web管理员 <%s>' % to_addr) msg['Subject'] = Header('来自SMTP-定时备份……', 'utf-8').encode() # 邮件正文是MIMEText: msg.attach(MIMEText('自动备份项目代码 file...', 'plain', 'utf-8')) # 添加附件就是加上一个MIMEBase,从本地读取一个图片: with open(filePath, 'rb') as f: # 设置附件的MIME和文件名,这里是png类型: mime = MIMEBase('image', 'png', filename='test.png') # 加上必要的头信息: mime.add_header('Content-Disposition', 'attachment', filename=ZipName) mime.add_header('Content-ID', '<0>') mime.add_header('X-Attachment-Id', '0') # 把附件的内容读进来: mime.set_payload(f.read()) # 用Base64编码: encoders.encode_base64(mime) # 添加到MIMEMultipart: msg.attach(mime) try: server = smtplib.SMTP(smtp_server, 25) # server.set_debuglevel(1) server.login(from_addr, password) a = server.sendmail(from_addr, [to_addr], msg.as_string()) return True except Exception: return False
# 删除文件 def delFile(): if os.path.exists(filePath): os.remove(filePath)
经测试,在windows很开就收到了,但上传到服务器又报错了:wordpress
/usr/bin/python^M: bad interpreter: No such file
是由于windows行结尾和linux行结尾标识不一样形成的。使用notepad++把文件转换为UNIX格式。测试
#!/usr/bin/python # coding=utf-8 import os, os.path import zipfile from email import encoders from email.header import Header from email.mime.base import MIMEBase from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.utils import parseaddr, formataddr import smtplib import datetime import os ZipName = datetime.datetime.now().strftime('%Y-%m-%d@%H.%M') + '.zip' filePath = "/home/wwwroot/tools/backup/" + ZipName # 压缩目录toZip def DirToZip(dirname, zipfilename): filelist = [] if os.path.isfile(dirname): filelist.append(dirname) else: for root, dirs, files in os.walk(dirname): for name in files: filelist.append(os.path.join(root, name)) try: zf = zipfile.ZipFile(zipfilename, "w", zipfile.zlib.DEFLATED) for tar in filelist: arcname = tar[len(dirname):] try: # 异常出如今文件名为中文 zf.write(tar, arcname) except: zf.write(tar, repr(arcname)[1:-1]) zf.close() return True except Exception as e: return False # 格式字符串 def _format_addr(s): name, addr = parseaddr(s) return formataddr((Header(name, 'utf-8').encode(), addr)) # 发送邮件 def sendMail(): print(ZipName) # 输入Email地址和口令: from_addr = 'admin@****.com' password = '123456' # 输入收件人地址: to_addr = '****@163.com' # 输入SMTP服务器地址: smtp_server = 'smtp.exmail.qq.com' # 邮件对象: msg = MIMEMultipart() msg['From'] = _format_addr('自动备份项目代码 <%s>' % from_addr) msg['To'] = _format_addr('Web管理员 <%s>' % to_addr) msg['Subject'] = Header('来自SMTP-定时备份……', 'utf-8').encode() # 邮件正文是MIMEText: msg.attach(MIMEText('自动备份项目代码 file...', 'plain', 'utf-8')) # 添加附件就是加上一个MIMEBase,从本地读取一个图片: with open(filePath, 'rb') as f: # 设置附件的MIME和文件名,这里是png类型: mime = MIMEBase('image', 'png', filename='test.png') # 加上必要的头信息: mime.add_header('Content-Disposition', 'attachment', filename=ZipName) mime.add_header('Content-ID', '<0>') mime.add_header('X-Attachment-Id', '0') # 把附件的内容读进来: mime.set_payload(f.read()) # 用Base64编码: encoders.encode_base64(mime) # 添加到MIMEMultipart: msg.attach(mime) try: server = smtplib.SMTP(smtp_server, 25) # server.set_debuglevel(1) server.login(from_addr, password) a = server.sendmail(from_addr, [to_addr], msg.as_string()) return True except Exception: return False # 删除文件 def delFile(): if os.path.exists(filePath): os.remove(filePath) if __name__ == '__main__': zipfile = DirToZip(r'/home/wwwroot/www', filePath) if zipfile: sending = sendMail() if sending: delFile()
成功发送邮件: