【问题标题】:python attaching mailBody into the e-mail not workingpython将电子邮件正文附加到电子邮件中不起作用
【发布时间】:2018-09-17 14:15:50
【问题描述】:

我有一个下面的脚本,它可以很好地用于 rsync,这个脚本实际上将文件从远程主机拉到服务器,从它在dest 文件夹下运行。

但是rsync 工作正常,但邮件部分基本上msg = 'message + "rsync process completed"' 没有作为电子邮件发送。

不知何故,我不知道我在做什么错!

import os
import sys
import subprocess
import argparse
import smtplib

#Dir Structure
dst = "/infralogs/external_dns_logs"
rsync_user = "root"
mailFrom = 'robo@helisis.com'
mailTo = 'robo@helisis.com'
mailSub = 'Rsync status'
msg = ""

parser = argparse.ArgumentParser()
parser.add_argument("-n","--hosts",dest="hosts",help="enter remote host/hosts name, comma seperated",metavar="HOSTS")
parser.add_argument("-s","--src",dest="source",help="source file/directory",metavar="SOURCE")
parser.add_argument("-e","--exclude",dest="exclude",help="Exclude files/Directories, comma seperated list",metavar="EXCLUDE")

if len(sys.argv) < 7:
    print(len(sys.argv))
    parser.print_help()
    parser.exit()

args = parser.parse_args()

def sync(host,dst):
    exclude = ""
    if not os.path.exists(dst):
        os.mkdir(dst)
    if ',' in args.exclude:
        for excl in args.exclude.split(','):
            exclude = exclude + " --exclude " + excl
        cmd = "rsync -e 'ssh -o StrictHostKeyChecking=no' -auPz %s %s@%s:%s %s/"%(exclude,rsync_user,host,args.source,dst)
    else:
        cmd = "rsync -e 'ssh -o StrictHostKeyChecking=no' -auPz --exclude %s %s@%s:%s %s/"%(args.exclude,rsync_user,host,args.source,dst)
    print(cmd)
    message = cmd
    p = subprocess.Popen(cmd,shell=True)
    p.wait()
    print("DONE")
    msg = message + "rsync process completed"

mailBody = "From: %s\nTo: %s\nSubject: %s\n\n%s" %(mailFrom,mailTo,mailSub,msg)

if ',' in args.hosts:
    for host in args.hosts.split(','):
        dest = dst + "/" + host
        sync(host,dest)
else:
    dest = dst + "/" + args.hosts
    sync(args.hosts,dest)

try:
    Mail = smtplib.SMTP('mailserver.global.helisis.com', 25, 'localhost.helisis.com')
    Mail.sendmail(mailFrom,mailTo,mailBody,msg)
    print("Mail Sent to %s" %(mailTo))
except:
    print("Mail Failed")

上述脚本在终端上输出结果:

$ ./log_rsync -n remote_Server -s /var/log/infoSec/ -e "null"

bind.log
           0 100%    0.00kB/s    0:00:00 (xfer#1, to-check=7/9)
default.log
       12769 100%   12.18MB/s    0:00:00 (xfer#2, to-check=6/9)
general.log
        9553 100%    4.56MB/s    0:00:00 (xfer#3, to-check=5/9)
lame-servers.log
         663 100%  129.49kB/s    0:00:00 (xfer#4, to-check=4/9)
network.log
           0 100%    0.00kB/s    0:00:00 (xfer#5, to-check=3/9)
notify.log
        3286 100%  356.55kB/s    0:00:00 (xfer#6, to-check=2/9)
queries.log
         578 100%   47.04kB/s    0:00:00 (xfer#7, to-check=1/9)
query-errors.log
           0 100%    0.00kB/s    0:00:00 (xfer#8, to-check=0/9)

sent 176 bytes  received 4303 bytes  814.36 bytes/sec
total size is 26849  speedup is 5.99
DONE
Mail Sent to robo@helisis.com

邮件服务工作正常,但是包含消息 msg = message + "rsync process completed"msg 变量没有收到发送带有主题的剩余电子邮件,但问题似乎与未正确调用或打开的 msg 部分有关.

只是另一种方式!

当我应用下面的方法时,我已经包含了To 地址、Subject 和消息,即 Rsync Process Completed Successfully.,它可以工作并发送电子邮件,但如果我想包含@,真正的问题仍然是一样的987654332@或者说想在这里公开msg部分,怎么可能!

EmailSender="robo@localhost.helisis.com"
EmailReceiver="robo@helisis.com"

msgBody='''From: dnsmailer <netrobo@helisis.com>
To: To Person <robo@helisis.com>
Subject: rsync Status from  infra-syslog

Rsync Process Completed Succesfully.
'''

if ',' in args.hosts:
    for host in args.hosts.split(','):
        dest = dst + "/" + host
        sync(host,dest)
else:
    dest = dst + "/" + args.hosts
    sync(args.hosts,dest)

try:
    smtpobj=smtplib.SMTP('mailserver.global.helisis.com', 25, 'localhost.helisis.com')
    smtpobj.sendmail(EmailSender,EmailReceiver,msgBody)
except Exception as e:
    print(e)

【问题讨论】:

  • 很难说没有更多信息...到底发生了什么?没有收到邮件?收到一封邮件但不包含您期望的内容?您能否向邮件服务器管理员索取一些日志以查看服务器上发生了什么?
  • @SergeBallesta,让我修改我的帖子以详细说明信息,谢谢输入.. 虽然邮件服务工作正常,但刚刚更新了帖子的详细信息。
  • 一个问题仍然不够明确。请准确地说出你得到什么和你期望什么。我现在认为问题不在邮寄部分,但我真的需要这些细节来给你一个相关的答案。
  • @SergeBallesta,是的,邮件正如我所说,我想要的是在电子邮件中获得msg 部分。
  • 如果多于一台主机,您希望每台主机一封邮件还是每台主机一行一封邮件?或者你真的可以说(全文)你得到什么和你期望什么?

标签: python subprocess


【解决方案1】:

问题是msg 是在sync 函数内部计算的(可以在循环中调用),然后就被遗忘了(意思是不存储)。

因此,当您想在邮件正文中使用它时,它不再可用。您必须在可用时使用它并直接为邮件正文提供内容,或者更好地将其存储在列表中,然后使用它来构建邮件正文。代码可能变成:

...
def sync(host,dst):
    ...
    message = cmd
    p = subprocess.Popen(cmd,shell=True)
    p.wait()
    print("DONE")
    return message + " rsync process completed"  # returns the msg to the caller

msglist = []             # a list to store the messages for the mail body

if ',' in args.hosts:
    for host in args.hosts.split(','):
        dest = dst + "/" + host
        msglist.append(sync(host,dest))
else:
    dest = dst + "/" + args.hosts
    msglist.append(sync(args.hosts,dest))

msg = "\n".join(msglist)                 # combine all messages, one per line
mailBody = "From: %s\nTo: %s\nSubject: %s\n\n%s" %(mailFrom,mailTo,mailSub,msg)

try:
    Mail = smtplib.SMTP('mailserver.global.helisis.com', 25, 'localhost.helisis.com')
    Mail.sendmail(mailFrom,mailTo,mailBody,msg)
    print("Mail Sent to %s" %(mailTo))
    Mail.bye()                  # cleaner to say goodbye to server...
    Mail.close()
except:
    print("Mail Failed")

【讨论】:

    【解决方案2】:

    您能否尝试使用 MIMEMultipart 发送消息。我应该以这种方式工作。

    import smtplib
    from email.mime.multipart import MIMEMultipart
    
    EmailSender = "robo@localhost.helisis.com"
    EmailReceiver = "robo@helisis.com"
    
    msgBody = '''From: dnsmailer <netrobo@helisis.com>
    To: To Person <robo@helisis.com>
    Subject: rsync Status from  infra-syslog
    
    Rsync Process Completed Succesfully.
    '''
    
    try:
        Mail = smtplib.SMTP('mailserver.global.helisis.com', 25, 'localhost.helisis.com')
        mail_obj = MIMEMultipart()
        mail_obj["From"] = EmailSender
        mail_obj["To"] = EmailReceiver
        mail_obj["Subject"] = "rsync Status from  infra-syslog."
        mail_obj.preamble = "rsync Status from  infra-syslog. "
        msgBody = "Rsync Process Completed Successfully!"  # Message body
        mail_obj.attach(MIMEText(message, 'plain'))
        Mail.sendmail(from_addr=[EmailSender], to_addrs=[EmailReceiver], msg=mail_obj.as_string())
        print("Mail Sent to %s" % (EmailReceiver))
    except Exception as error:
        print("Mail Failed - {}".format(error))
    

    【讨论】:

    • @Vijay 让我试试这个。
    • message = "&lt;html&gt;&lt;h1&gt; Hello World! &lt;/h1&gt;&lt;/html&gt;" 在这里您可以添加您的动态消息,例如同步状态。
    • Vijay,我提到的另一种可行的方法,我想看到的是msg = message + "rsync process completed",其中message 分配给cmd。我需要在消息正文中包含或打开 msg 变量。即使使用 MIMEMultipart ,所以发送邮件不是问题,唯一的问题是 msg 在发送电子邮件时没有得到扩展。
    • 味精没有得到扩展?请您详细说明一下?
    • 你为什么分配message = "cmd"而不是message = cmd
    【解决方案3】:

    冒昧的把对我有用的电子邮件放在这里,因为 smtplib 抛出了一些我之前应用的错误,下面是工作的电子邮件部分,可能有人会寻找相同的 :-)

    非常感谢 @Serge 和 @Vijay 在这方面的帮助..

    from email.mime.multipart import MIMEMultipart
    from email.mime.text import MIMEText
    import smtplib
    
    
    email_sender = "syslogger@helisis.com"
    email_receiver = "robo@helisis.com, robo01@helisis.com, robo02@helisis.com"
    
    
    try:
        Mail = smtplib.SMTP('mailserver.global.helisis.com', 25, 'localhost.helisis.com')
        mail_obj = MIMEMultipart('alternative')
        mail_obj["From"] = email_sender
        mail_obj["To"] = email_receiver
        mail_obj["Cc"] = "someone@helisis.com"
        mail_obj["Subject"] = "rsync Status from  infra-syslog."
        mail_obj.preamble = "rsync Status from  infra-syslog. "
        msgBody = "Rsync Process Completed Successfully!"  # Message body
        mail_obj.attach(MIMEText(msg, 'plain'))
        Mail.sendmail(from_addr=[email_sender], to_addrs=[email_receiver],msg=mail_obj.as_string())
        print("Mail Sent to %s" % (email_sender))
    except Exception as error:
        print("Mail Failed - {}".format(error))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-17
      • 2019-06-05
      • 2014-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多