Linux 上 Heirloom mailx 的 HTML 电子邮件

Linux 上 Heirloom mailx 的 HTML 电子邮件

我一直在尝试从 Linux 服务器上的 mailx 发送 html 电子邮件。

几点注意事项:

  • 我必须指定一个 smtp 服务器,因此我无法使用 sendmail (这不是我可以更改的内容)
  • 我无法安装 mutt 等第三方东西。我必须使用 mail 或 mailx
  • 由于我的 mail/x 版本是传家宝,所以我没有 --append 或 -a (附加标头选项)
  • 不确定这是否有帮助,但我的 Linux 发行版是 7.3 (Maipo)

我在 stackoverflow 上的大多数帖子中看到的关于我的案例的内容:

mailx -v -S smtp=SERVER -s "$(echo -e "This is the subject\nContent-Type: text/html")" -r FROM TO < htmlmail.txt

在我的例子中,这只是返回一封纯文本电子邮件。

所以这是我到目前为止所尝试过的:

尝试1:

我在一篇文章中看到添加 Content-Disposition: inline。

mailx -v -S smtp=SERVER -s "$(echo -e "This is the subject v1\nContent-Type: text/html\nMIME-Version: 1.0\nContent-Disposition: inline")" -r FROM TO < htmlmail.txt

这最终会发送一封 html 电子邮件,但由于标头包含在正文中,因此输出如下:

内容处置:内联消息 ID:用户代理:Heirloom mailx 12.5 7/5/10 MIME 版本:1.0 内容类型:文本/纯文本;字符集=us-ascii 内容传输编码:7 位你好世界

尝试2:

所以我不希望在正文中打印标题。所以我尝试删除 Content-Disposition: inline

mailx -v -S smtp=SERVER -s "$(echo -e "This is the subject v2\nContent-Type: text/html\nMIME-Version: 1.0")" -r FROM TO < htmlmail.txt

这最终会发送一封简单的测试电子邮件,如下所示:

<html> <b>Hello World</b> </html>

尝试3:

尝试翻转内容类型和哑剧版本

mailx -v -S SERVER -s "$(echo -e "This is the subject v3\nMIME-Version: 1.0\nContent-Type: text/html")" -r FROM TO < htmlmail.txt

我最终没有收到来自此代码的电子邮件

尝试4:

我在网上看到尝试另一个标题来帮助找到问题所在。所以我添加了标头选项来设置邮件优先级。

mailx -v -S smtp=SERVER -s "$(echo -e "This is a subject v4\nContent-Type: text/html\nX-Priority: 1 (Highest)")" -r FROM TO < htmlmail.txt

最终发送了一封高优先级的电子邮件,但全部都是纯文本形式。

尝试5:

我在之前的尝试中添加了 MIME 标头

mailx -v -S smtp=SERVER -s "$(echo -e "This is a subject v5\nMIME-Version: 1.0\nContent-Type: text/html\nX-Priority: 1 (Highest)")" -r FROM TO < htmlmail.txt

这最终发送了一封正文中包含标题的电子邮件,并且优先级未设置为高......奇怪

X 优先级:1(最高) 消息 ID:用户代理:Heirloom mailx 12.5 7/5/10 MIME 版本:1.0 内容类型:文本/纯文本;字符集=us-ascii 内容传输编码:7 位你好世界

毕竟,我尝试了上述尝试的许多其他改编,但它们没有产生新的输出。

因此,我们乐意接受任何建议或想法!请记住我上面列出的限制...我知道它们限制了我的选择,但这不是我能控制的。

谢谢你的时间!

答案1

首先一些上下文:我使用 heirloom-mailx 版本作为以下线程中的版本: https://serverfault.com/questions/136106/what-package-to-install-for-sending-emails-from-localhost-ubuntu

我使用的是 Ubuntu 16.04 Xenial。也在 Ubuntu Server 16.04 上尝试过。

为了发送电子邮件,我使用以下函数通过 mailx(bash 中的传家宝 mailx)发送邮件:

sendmail() {
#Sending Report Email
heirloom-mailx -a $2 -v -s ""$(echo -e "subject 3\nContent-Type: text/html")"" \
-S smtp-use-starttls \
-S ssl-verify=ignore \
-S smtp-auth=login \
-S smtp=smtp://mail.mymailserver:port \
-S from="[email protected]" \
-S [email protected] \
-S smtp-auth-password='password' \
-S ssl-verify=ignore \
$1 < body.html
}

其中 $2 是附件,$1 是目的地。注意: 1. 附加文件也会打印在正文内,但如果您只想发送不带附件的 html 文件,这可能对您有用。 2. 使用“-v”选项会打印详细信息,因此您可能会遇到可以忽略的 .mime.types 问题。如果您不想在 mailx 上出现详细信息,请删除该选项。 3. 如果使用“-a”选项,您仍会在正文中看到以下内容: 这是一条 MIME 格式的多部分消息。 --=-=fFPa7dLqoSF1TGj-YDc2k8bdvmjpix_4sKFT=-= 内容类型:文本/纯文本;字符集=US-ASCII 内容处置:内联

在本例中,我附加了一个纯文本文件。从命令中删除“-a $2”,您就可以打印 html 消息了。所以最终结果将是:

sendmail() {
    #Sending Report Email
    heirloom-mailx -s ""$(echo -e "subject 3\nContent-Type: text/html")"" \
    -S smtp-use-starttls \
    -S ssl-verify=ignore \
    -S smtp-auth=login \
    -S smtp=smtp://mail.mymailserver:port \
    -S from="[email protected]" \
    -S [email protected] \
    -S smtp-auth-password='password' \
    -S ssl-verify=ignore \
    $1 < body.html
    }

尝试一下并告诉我。我已经在我的终端上进行了测试并且它有效。

答案2

如果您被困在无法安装新软件(包括适当的 MTA)的服务器上,也许最简单的解决方法是使用包含 SMTP 库的语言编写一个简单的脚本。我的选择是Python。这是示例代码的简单改编文档。

#!/usr/bin/env python3

import smtplib
from argparse import ArgumentParser
from email.message import EmailMessage


def main():
    parser = ArgumentParser(description="""\
Quick and dirty mailx replacement for sending a HTML message via a
specific SMTP server. Based on examples from
https://docs.python.org/3/library/email.examples.html#email-examples
""")
    parser.add_argument('-H', '--html-file', required=True,
                        help="The HTML body to send (required)")
    parser.add_argument('-S', '--smtp-server', required=True,
                        help='The SMTP server to use (required)')
    parser.add_argument('-s', '--subject', required=True,
                        help='Subject (required)')
    parser.add_argument('-r', '--return-path', required=True,
                        help='Return-Path / envelope sender (required)')
    parser.add_argument('recipients', nargs='+')
    args = parser.parse_args()

    msg = EmailMessage()
    msg['Subject'] = args.subject
    msg['To'] = ', '.join(args.recipients)
    msg['From'] = args.return_path
    # The examples suggest you should mess with the preamble, but you should not

    with open(args.html_file, 'r') as html:
        msg.set_content(html.read(), subtype='html')

    with smtplib.SMTP(args.smtp_server) as s:
        s.send_message(msg)


if __name__ == '__main__':
    main()

用法:

python3 path/to/script.py -S SERVER -s "This is the subject" \
    -r FROM -H htmlmail.html TO

这针对的是 Python 版本 3。如果您使用的是旧平台,也许您只有 Python 2;但如何适应这一点应该是相当明显的(主要使用email.message.Message遗留类,而不是 3.3 中引入的大修和现代化EmailMessage并在 3.5 中正式发布)。

答案3

我刚刚想通了,回到你的第一个案例,当你将标头注入主题字段时,你将 mailx 制作的标头(即明文的标头)推送到正文中。这意味着,它认为您的正文从真实标头的末尾开始,并接受推送的标头。这意味着您可以使用 HTML 来解决您的问题。

在注入标头的末尾,输入

<html><!--

这将开始一个 html 注释!

在你真正的、预期的身体开始时,把

-->

关闭评论!这会将推动的标头隐藏在远离主体的位置!

相关内容