使用Python发送邮件附件以定时备份MySQL的教程


Posted in Python onApril 25, 2015

最近迁移了wordpress,系统升级为CentOS 6,很奇怪的一个问题,在原来CentOS 5.8下用的很正常的定时备份数据库并通过邮件发送的脚本不能发送附件,其他都正常,邮件内容也是uuencode生成的文件编码,但是就是不产生附件.而且找不出原因,望有知道的不吝赐教.

为了解决这一问题,我用Python写了一个mail客户端,可以发送附件,是一个命令行程序.废话不多说.贴代码:

#!/usr/bin/env python
#-*- coding: utf8 -*-
'''
#=============================================================================
#   FileName: mail.py
#     Desc: To send email
#    Author: cold
#    Email: wh_linux@126.com
#   HomePage: http://www.linuxzen.com
#   Version: 0.0.1
#  LastChange: 2012-04-21 16:37:20
#   History:
#=============================================================================
'''

'''
用于发送邮件,可以发送附件
命令行程序
'''
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import sys



# 打印帮助信息
def helpinfo():
  print '''
  Useage: pymail -u user@domain -p passwd -h smtp server host -t to who [-a attachment file path] [-n attachment name]
  Useage: email content use . to end
  -h specify smtp server host
  -u which user you login the smtp server,and must with it domain
  -p the password of the smtp user
  -t The email recipient,multiple addresses can use ',' split
  -a Add attachment
  -n Secify attachment name in the email

  Author:cold(wh_linux@126.com)
  Homepge:http://www.linuxzen.com
  '''


# 所有选项
options = ['-t', '-a', '-n', '-h', '-u', '-p', '-s']

# 获取选项长度
argvnum = len(sys.argv)

# 检测命令行参数
for i in range(argvnum):
  if ( i %2 != 0):
    if (sys.argv[i] not in options):
      print 'Unknow option ', sys.argv[i] , ', Please use -h see help!'
      sys.exit(3)

# 如果是-h或者没有命令行参数则显示帮助
try:
  if sys.argv[1] == '-h' or len(sys.argv) == 0:
    helpinfo()
except:
  helpinfo()


# 检测-n参数
if ('-n' in sys.argv) and ('-a' not in sys.argv):
  print 'Error:option "-n" must use after -a'
  sys.exit(2)

# 下面则是获取各个参数内容
try:
  tmpmailto = sys.argv[sys.argv.index('-t') + 1]
  if ',' in tmpmailto:
    mailto = tmpmailto.split(',')
  else:
    mailto = [tmpmailto,]
except ValueError:
  print 'Error: need Mail Recipient'
  sys.exit(1)

haveattr=True

try:
  attrpath = sys.argv[sys.argv.index('-a') + 1]
  try:
    attrname = sys.argv[sys.argv.index('-n') +1 ]
  except ValueError:
    attrname = attrpath.split('/')[-1]
except:
  attrname = None
  haveattr = False
  attrpath = None


try:
  mail_host = sys.argv[sys.argv.index('-h') +1]
except ValueError:
  print 'Waring: No specify smtp server use 127.0.0.1'
  mail_host = '127.0.0.1'


try:
  mail_useremail = sys.argv[sys.argv.index('-u') +1]
except ValueError:
  print 'Waring: No specify user, use root'
  mail_useremail = 'root@localhost'

try:
  mail_sub = sys.argv[sys.argv.index('-s') + 1]
except:
  mail_sub = 'No Subject'

mail_user = mail_useremail.split('@')[0]
mail_postfix = mail_useremail.split('@')[1]

try:
  mail_pass = sys.argv[sys.argv.index('-p') +1]
except ValueError:
  mail_pass = ''




# 定义邮件发送函数
def send_mail(to_list, sub, content, haveattr, attrpath, attrname):
  me = mail_user + "<" + mail_user+"@"+mail_postfix +">"

  # 判断是否有附件
  if (haveattr):
    if (not attrpath):
      print 'Error : no input file of attachments'
      return False

    # 有附件则创建一个带附件的实例
    msg = MIMEMultipart()

    # 构造附件
    att = MIMEText(open(attrpath, 'rb').read(),'base64', 'utf8')
    att["Content-Type"] = 'application/octest-stream'
    att["Content-Disposition"] = 'attachment;filename="'+ attrname +'"'
    msg.attach(att)
    msg.attach(MIMEText(content))
  else:
    # 无责创建一个文本的实例
    msg = MIMEText(content)


  # 邮件头
  msg['Subject'] = sub
  msg['From'] = me
  msg['To'] = ";".join(to_list)
  try:
    # 发送邮件
    s = smtplib.SMTP()
    s.connect(mail_host)
    if (mail_host != '127.0.0.1'):
      s.login(mail_user, mail_pass)
    s.sendmail(me, to_list, msg.as_string())
    s.close()
    return True
  except Exception, e:
    print str(e)
    return False

if __name__ == '__main__':

  try:
    content = ''
    while True:
      c = raw_input('')
      if c == '.':
        break
      content += c + '\n'
  except EOFError:
    for line in sys.stdin:
      content += line
  if send_mail(mailto, mail_sub, content, haveattr, attrpath, attrname):
    print "Success"
  else:
    print "Failed"

将这个脚本保存为pymail放到/usr/bin/下,并赋予其执行权限:

chmod +x /usr/bin/pymail

可以使用 -h指定smtp发件服务器,默认认为指定-h需要认证, 所以就需要smtp服务器支持认证,同时需要-u指定用户名(需加"@域名"),-p指定密码. 如果不指定-h就会使用本地smtp服务器,默认不需要认证,所以本地的smtp服务器就不能支持认证,同时不需指定-u,-p参数

-t 指定收件人多个可用,号分割.
-a 指定附件路径
-n 指定附件名(可省略)
-h 显示帮助信息.
-s 指定邮件主题

执行后会要求输入邮件内容,写完用.结束 也可以用管道下面给出几个实例:

#使用本地smtp服务发送
echo 'linuxzen.com backup' | pymail -s "Linuxzen backup" -t 123456@qq.com -a /tmp/linuxzen.tar.gz
# 使用126邮箱发送
echo 'linuxzen.com backup' | pymail -u linuxzen@126.com -p linuxzen.com -h smtp.126.com -s 'Linuxzen backup " -t 123456@qq.com -a /tmp/linuxzen.tar.gz 

# 不使用管道发送
pymail -u linuxzen@126.com -p linuxzen.com -h smtp.126.com -s 'hello world' -t 123456@qq.com -a /tmp/linuxzen.tar.gz
Hello
this is a test mail
.

下面之前使用的mysql定时备份的脚本:

#!/bin/bash
export PATH=/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
DATE=`date +%Y%m%d`
mysqldump -u root blogdata > /tmp/blogdate."$DATE".sql
cd /tmp
tar -zcf blogdata."$DATE".sql.tar.gz blogdata."$DATE".sql
uuencode blogdata."$DATE".sql.tar.gz blogdata."$DATE".sql.tar.gz | mail -s 'MySQL Backup' 123456@qq.com

没有命令uuencode安装sharutils包即可

yum -y install sharutils

然后使用crontab调用这个脚本定时执行,前面说了 这个脚本在CentOS5.x下正常工作,但是放到CentOS6下就不带附件,所以使用我们自己编写的python脚本脚本内容如下:
 

#!/bin/bash
export PATH=/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
DATE=`date +%Y%m%d`
mysqldump -u root blogdata > /tmp/myblog."$DATE".sql
cd /tmp
tar -zcf blogdata."$DATE".sql.tar.gz myblog."$DATE".sql
echo 'MySQL backup' | pymail -u linuzen@126.com -p linuxzen.com -h smtp.126.com -s 'MySQL backup' -a /tmp/blogdata."$DATE".sql.tar.gz -t 123456@qq.com
我们使用126邮箱来发送 这样就可以把自带的sendmail 停掉:
service sendmail stop
chkonfig --del sendmail

 

Python 相关文章推荐
零基础写python爬虫之爬虫的定义及URL构成
Nov 04 Python
Python实现CET查分的方法
Mar 10 Python
python实现爬虫统计学校BBS男女比例之数据处理(三)
Dec 31 Python
浅谈django model的get和filter方法的区别(必看篇)
May 23 Python
Python 实现Windows开机运行某软件的方法
Oct 14 Python
Python中对数组集进行按行打乱shuffle的方法
Nov 08 Python
python PrettyTable模块的安装与简单应用
Jan 11 Python
浅谈python3.x pool.map()方法的实质
Jan 16 Python
PyQt打开保存对话框的方法和使用详解
Feb 27 Python
基于OpenCV python3实现证件照换背景的方法
Mar 22 Python
Python函数参数类型及排序原理总结
Dec 19 Python
python GUI框架pyqt5 对图片进行流式布局的方法(瀑布流flowlayout)
Mar 12 Python
安装Python的web.py框架并从hello world开始编程
Apr 25 #Python
用Python编写一个基于终端的实现翻译的脚本
Apr 24 #Python
Python的Bottle框架中获取制定cookie的教程
Apr 24 #Python
利用Python的装饰器解决Bottle框架中用户验证问题
Apr 24 #Python
在Python中使用mongoengine操作MongoDB教程
Apr 24 #Python
python使用arp欺骗伪造网关的方法
Apr 24 #Python
python使用wxPython打开并播放wav文件的方法
Apr 24 #Python
You might like
PHP脚本的10个技巧(5)
2006/10/09 PHP
Zend Framework教程之请求对象的封装Zend_Controller_Request实例详解
2016/03/07 PHP
PHP依赖注入原理与用法分析
2018/08/21 PHP
php如何把表单内容提交到数据库
2019/07/08 PHP
document.getElementById为空或不是对象的解决方法
2010/01/24 Javascript
可选择和输入的下拉列表框示例
2013/11/05 Javascript
通过JQuery将DIV的滚动条滚动到指定的位置方便自动定位
2014/05/05 Javascript
node.js中的events.emitter.once方法使用说明
2014/12/10 Javascript
JS中call/apply、arguments、undefined/null方法详解
2016/02/15 Javascript
vue2.0 自定义 饼状图 (Echarts)组件的方法
2018/03/02 Javascript
vue+SSM实现验证码功能
2018/12/07 Javascript
对layui中的onevent 和event的使用详解
2019/09/06 Javascript
Vue记住滚动条和实现下拉加载的完美方法
2020/07/31 Javascript
[47:42]完美世界DOTA2联赛PWL S2 GXR vs Ink 第一场 11.19
2020/11/20 DOTA
Python提取网页中超链接的方法
2016/09/18 Python
Python错误: SyntaxError: Non-ASCII character解决办法
2017/06/08 Python
Python实现的json文件读取及中文乱码显示问题解决方法
2018/08/06 Python
PyCharm 创建指定版本的 Django(超详图解教程)
2019/06/18 Python
python操作kafka实践的示例代码
2019/06/19 Python
使用 python pyautogui实现鼠标键盘控制功能
2019/08/04 Python
Python实现把多维数组展开成DataFrame
2019/11/30 Python
Tensorflow 多线程与多进程数据加载实例
2020/02/05 Python
英国现代绅士品牌:Hackett
2017/12/17 全球购物
我们是伦敦女孩:WalG
2018/01/08 全球购物
英国和爱尔兰最大的地毯零售商:Kukoon
2018/12/17 全球购物
迪卡侬波兰体育用品商店:Decathlon波兰
2020/03/31 全球购物
vue项目实现分页效果
2021/03/24 Vue.js
社区党总支书记先进事迹材料
2014/01/24 职场文书
xxx同志考察材料
2014/02/07 职场文书
《一件运动衫》教学反思
2014/02/19 职场文书
《第一朵杏花》教学反思
2014/04/16 职场文书
2014年度个人工作总结范文
2015/03/09 职场文书
幼儿园安全管理制度
2015/08/05 职场文书
2016习总书记系列重要讲话心得体会
2016/01/15 职场文书
如何用JavaScipt测网速
2021/05/09 Javascript
pytorch中的model=model.to(device)使用说明
2021/05/24 Python