使用Python发送邮件附件以定时备份MySQL的教程
最近迁移了wordpress,系统升级为CentOS6,很奇怪的一个问题,在原来CentOS5.8下用的很正常的定时备份数据库并通过邮件发送的脚本不能发送附件,其他都正常,邮件内容也是uuencode生成的文件编码,但是就是不产生附件.而且找不出原因,望有知道的不吝赐教.
为了解决这一问题,我用Python写了一个mail客户端,可以发送附件,是一个命令行程序.废话不多说.贴代码:
#!/usr/bin/envpython #-*-coding:utf8-*- ''' #============================================================================= #FileName:mail.py #Desc:Tosendemail #Author:cold #Email:wh_linux@126.com #HomePage:http://www.linuxzen.com #Version:0.0.1 #LastChange:2012-04-2116:37:20 #History: #============================================================================= ''' ''' 用于发送邮件,可以发送附件 命令行程序 ''' importsmtplib fromemail.mime.textimportMIMEText fromemail.mime.multipartimportMIMEMultipart importsys #打印帮助信息 defhelpinfo(): print''' Useage:pymail-uuser@domain-ppasswd-hsmtpserverhost-ttowho[-aattachmentfilepath][-nattachmentname] Useage:emailcontentuse.toend -hspecifysmtpserverhost -uwhichuseryouloginthesmtpserver,andmustwithitdomain -pthepasswordofthesmtpuser -tTheemailrecipient,multipleaddressescanuse','split -aAddattachment -nSecifyattachmentnameintheemail Author:cold(wh_linux@126.com) Homepge:http://www.linuxzen.com ''' #所有选项 options=['-t','-a','-n','-h','-u','-p','-s'] #获取选项长度 argvnum=len(sys.argv) #检测命令行参数 foriinrange(argvnum): if(i%2!=0): if(sys.argv[i]notinoptions): print'Unknowoption',sys.argv[i],',Pleaseuse-hseehelp!' sys.exit(3) #如果是-h或者没有命令行参数则显示帮助 try: ifsys.argv[1]=='-h'orlen(sys.argv)==0: helpinfo() except: helpinfo() #检测-n参数 if('-n'insys.argv)and('-a'notinsys.argv): print'Error:option"-n"mustuseafter-a' sys.exit(2) #下面则是获取各个参数内容 try: tmpmailto=sys.argv[sys.argv.index('-t')+1] if','intmpmailto: mailto=tmpmailto.split(',') else: mailto=[tmpmailto,] exceptValueError: print'Error:needMailRecipient' sys.exit(1) haveattr=True try: attrpath=sys.argv[sys.argv.index('-a')+1] try: attrname=sys.argv[sys.argv.index('-n')+1] exceptValueError: attrname=attrpath.split('/')[-1] except: attrname=None haveattr=False attrpath=None try: mail_host=sys.argv[sys.argv.index('-h')+1] exceptValueError: print'Waring:Nospecifysmtpserveruse127.0.0.1' mail_host='127.0.0.1' try: mail_useremail=sys.argv[sys.argv.index('-u')+1] exceptValueError: print'Waring:Nospecifyuser,useroot' mail_useremail='root@localhost' try: mail_sub=sys.argv[sys.argv.index('-s')+1] except: mail_sub='NoSubject' mail_user=mail_useremail.split('@')[0] mail_postfix=mail_useremail.split('@')[1] try: mail_pass=sys.argv[sys.argv.index('-p')+1] exceptValueError: mail_pass='' #定义邮件发送函数 defsend_mail(to_list,sub,content,haveattr,attrpath,attrname): me=mail_user+"<"+mail_user+"@"+mail_postfix+">" #判断是否有附件 if(haveattr): if(notattrpath): print'Error:noinputfileofattachments' returnFalse #有附件则创建一个带附件的实例 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() returnTrue exceptException,e: printstr(e) returnFalse if__name__=='__main__': try: content='' whileTrue: c=raw_input('') ifc=='.': break content+=c+'\n' exceptEOFError: forlineinsys.stdin: content+=line ifsend_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.combackup'|pymail-s"Linuxzenbackup"-t123456@qq.com-a/tmp/linuxzen.tar.gz #使用126邮箱发送 echo'linuxzen.combackup'|pymail-ulinuxzen@126.com-plinuxzen.com-hsmtp.126.com-s'Linuxzenbackup"-t123456@qq.com-a/tmp/linuxzen.tar.gz #不使用管道发送 pymail-ulinuxzen@126.com-plinuxzen.com-hsmtp.126.com-s'helloworld'-t123456@qq.com-a/tmp/linuxzen.tar.gz Hello thisisatestmail .
下面之前使用的mysql定时备份的脚本:
#!/bin/bash exportPATH=/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-urootblogdata>/tmp/blogdate."$DATE".sql cd/tmp tar-zcfblogdata."$DATE".sql.tar.gzblogdata."$DATE".sql uuencodeblogdata."$DATE".sql.tar.gzblogdata."$DATE".sql.tar.gz|mail-s'MySQLBackup'123456@qq.com
没有命令uuencode安装sharutils包即可
yum-yinstallsharutils
然后使用crontab调用这个脚本定时执行,前面说了这个脚本在CentOS5.x下正常工作,但是放到CentOS6下就不带附件,所以使用我们自己编写的python脚本脚本内容如下:
#!/bin/bash exportPATH=/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-urootblogdata>/tmp/myblog."$DATE".sql cd/tmp tar-zcfblogdata."$DATE".sql.tar.gzmyblog."$DATE".sql echo'MySQLbackup'|pymail-ulinuzen@126.com-plinuxzen.com-hsmtp.126.com-s'MySQLbackup'-a/tmp/blogdata."$DATE".sql.tar.gz-t123456@qq.com我们使用126邮箱来发送这样就可以把自带的sendmail停掉:
servicesendmailstop chkonfig--delsendmail