Linux 使用 shell 脚本发送 HTML 邮件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3317174/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 20:17:33  来源:igfitidea点击:

Sending HTML mail using a shell script

htmllinuxemailbashsendmail

提问by Tree

How can I send an HTML email using a shell script?

如何使用 shell 脚本发送 HTML 电子邮件?

采纳答案by álvaro González

First you need to compose the message. The bare minimum is composed of these two headers:

首先,您需要撰写消息。最低限度由这两个标头组成:

MIME-Version: 1.0
Content-Type: text/html

... and the appropriate message body:

...以及相应的消息正文:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head><title></title>
</head>
<body>

<p>Hello, world!</p>

</body>
</html>

Once you have it, you can pass the appropriate information to the mailcommand:

获得后,您可以将适当的信息传递给mail命令:

body = '...'

echo $body | mail \
-a "From: [email protected]" \
-a "MIME-Version: 1.0" \
-a "Content-Type: text/html" \
-s "This is the subject" \
[email protected]

This is an oversimplified example, since you also need to take care of charsets, encodings, maximum line length... But this is basically the idea.

这是一个过于简单的例子,因为您还需要处理字符集、编码、最大行长度……但这基本上就是这个想法。

Alternatively, you can write your script in Perl or PHP rather than plain shell.

或者,您可以使用 Perl 或 PHP 而不是普通 shell 编写脚本。

Update

更新

A shell script is basically a text file with Unix line endings that starts with a line called shebangthat tells the shell what interpreter it must pass the file to, follow some commands in the language the interpreter understands and has execution permission (in Unix that's a file attribute). E.g., let's say you save the following as hello-world:

shell 脚本基本上是一个文本文件,以 Unix 行结尾,以一行名为shebang的行开头,它告诉 shell 它必须将文件传递给哪个解释器,遵循解释器理解的语言中的一些命令并具有执行权限(在 Unix 中这是一个文件属性)。例如,假设您将以下内容另存为hello-world

#!/bin/sh

echo Hello, world!

Then you assign execution permission:

然后你分配执行权限:

chmod +x hello-world

And you can finally run it:

你终于可以运行它了:

./hello-world

Whatever, this is kind of unrelated to the original question. You should get familiar with basic shell scripting before doing advanced tasks with it. Here you are a couple of links about bash, a popular shell:

无论如何,这与原始问题无关。在使用它执行高级任务之前,您应该熟悉基本的 shell 脚本。这里有几个关于bash的链接,一个流行的 shell:

http://www.gnu.org/software/bash/manual/html_node/index.html

http://www.gnu.org/software/bash/manual/html_node/index.html

http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO.html

http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO.html

回答by mdma

The tags include 'sendmail' so here's a solution using that:

标签包括“sendmail”,所以这里有一个使用它的解决方案:

(
echo "From: [email protected] "
echo "To: [email protected] "
echo "MIME-Version: 1.0"
echo "Content-Type: multipart/alternative; " 
echo ' boundary="some.unique.value.ABC123/server.xyz.com"' 
echo "Subject: Test HTML e-mail." 
echo "" 
echo "This is a MIME-encapsulated message" 
echo "" 
echo "--some.unique.value.ABC123/server.xyz.com" 
echo "Content-Type: text/html" 
echo "" 
echo "<html> 
<head>
<title>HTML E-mail</title>
</head>
<body>
<a href='http://www.google.com'>Click Here</a>
</body>
</html>"
echo "------some.unique.value.ABC123/server.xyz.com--"
) | sendmail -t

A wrapper for sendmail can make this job easier, for example, mutt:

sendmail 的包装器可以使这项工作更容易,例如,mutt

mutt -e 'set content_type="text/html"' [email protected] -s "subject" <  message.html

回答by Matti Pastell

Another option is the sendEmail script http://caspian.dotconf.net/menu/Software/SendEmail/, it also allows you to set the message type as html and include a file as the message body. See the link for details.

另一个选项是 sendEmail 脚本http://caspian.dotconf.net/menu/Software/SendEmail/,它还允许您将消息类型设置为 html 并包含一个文件作为消息正文。有关详细信息,请参阅链接。

回答by Ashaman

Another option is using msmtp.

另一种选择是使用 msmtp。

What you need is to set up your .msmtprc with something like this (example is using gmail):

你需要的是用这样的东西设置你的 .msmtprc (例子是使用 gmail):

account default
host smtp.gmail.com
port 587
from [email protected]
tls on
tls_starttls on
tls_trust_file ~/.certs/equifax.pem
auth on
user [email protected]
password <password>
logfile ~/.msmtp.log

Then just call:

然后只需调用:

(echo "Subject: <subject>"; echo; echo "<message>") | msmtp <[email protected]>

in your script

在你的脚本中

Update: For HTML mail you have to put the headers as well, so you might want to make a file like this:

更新:对于 HTML 邮件,您还必须放置标题,因此您可能想要制作一个这样的文件:

From: [email protected]
To: [email protected]
Subject: Important message
Mime-Version: 1.0
Content-Type: text/html

<h1>Mail body will be here</h1>
The mail body <b>should</b> start after one blank line from the header.

And mail it like

然后像邮寄一样

cat email-template | msmtp [email protected]

The same can be done via command line as well, but it might be easier using a file.

同样可以通过命令行完成,但使用文件可能更容易。

回答by Joshua Gruber

In addition to the correct answer by mdma, you can also use the mail command as follows:

除了mdma的正确答案,还可以使用mail命令如下:

mail [email protected] -s"Subject Here" -a"Content-Type: text/html; charset=\"us-ascii\""

you will get what you're looking for. Don't forget to put <HTML>and </HTML>in the email. Here's a quick script I use to email a daily report in HTML:

你会得到你想要的。不要忘记把<HTML></HTML>放在电子邮件中。这是我用来通过电子邮件发送每日 HTML 报告的快速脚本:

#!/bin/sh
(cat /path/to/tomorrow.txt mysql -h mysqlserver -u user -pPassword Database -H -e "select statement;" echo "</HTML>") | mail [email protected] -s"Tomorrow's orders as of now" -a"Content-Type: text/html; charset=\"us-ascii\""

回答by Kevin Zhu

So far I have found two quick ways in cmd linux

到目前为止,我在 cmd linux 中找到了两种快速方法

  1. Use old school mail
  1. 使用旧学校邮件

mail -s "$(echo -e "This is Subject\nContent-Type: text/html")" [email protected] < mytest.html

mail -s "$(echo -e "This is Subject\nContent-Type: text/html")" [email protected] < mytest.html

  1. Use mutt
  1. 使用笨蛋

mutt -e "my_hdr Content-Type: text/html" [email protected] -s "subject" < mytest.html

mutt -e "my_hdr Content-Type: text/html" [email protected] -s "subject" < mytest.html

回答by Mykhaylo Adamovych

cat > mail.txt <<EOL
To: <email>
Subject: <subject>
Content-Type: text/html

<html>
$(cat <report-table-*.html>)
This report in <a href="<url>">SVN</a>
</html>

EOL

And then:

进而:

sendmail -t < mail.txt

回答by sugunan

Mime header and from, to address also can be included in the html file it self.

Mime 标头和 from、to 地址也可以包含在它自己的 html 文件中。

Command

命令

cat cpu_alert.html | /usr/lib/sendmail -t

cpu_alert.html file sample.

cpu_alert.html 文件示例。

From: [email protected]
To: [email protected]
Subject: CPU utilization heigh
Mime-Version: 1.0
Content-Type: text/html

<h1>Mail body will be here</h1>
The mail body should start after one blank line from the header.

Sample code available here: http://sugunan.net/git/slides/shell/cpu.php

此处提供的示例代码:http: //sugunan.net/git/slides/shell/cpu.php

回答by fiffy

Heres mine (given "mail" is configured correctly):

这是我的(给定“邮件”配置正确):

scanuser@owncloud:~$ vi sendMailAboutNewDocuments.sh

scanuser@owncloud:~$ vi sendMailAboutNewDocuments.sh

mail -s "You have new mail" -a "Content-type: text/html" -a "From: [email protected]"  << EOF
<html>
<body>
Neues Dokument: <br>
<a href="https://xxx/index.php/apps/files/?dir=/Post">Hier anschauen</a>
</body>
</html>

EOF

to make executable:

使可执行文件:

chmod +x sendMailAboutNewDocuments.sh

then call:

然后调用:

./sendMailAboutNewDocuments.sh [email protected] test.doc

回答by Shawn Q

Using CentOS 7's default mailx (appears as heirloom-mailx), I've simplified this to just using a text file with your required headers and a static boundary for multipart/mixed and multipart/alternative setup.

使用 CentOS 7 的默认 mailx(显示为 heirloom-mailx),我已将其简化为仅使用带有所需标题的文本文件和多部分/混合和多部分/替代设置的静态边界。

I'm sure you can figure out multipart/related if you want with the same setup.

如果您想使用相同的设置,我相信您可以找出 multipart/related 。

test.txt:

测试.txt:

--000000000000f3b2150570186a0e
Content-Type: multipart/alternative; boundary="000000000000f3b2130570186a0c"

--000000000000f3b2130570186a0c
Content-Type: text/plain; charset="UTF-8"

This is my plain text stuff here, in case the email client does not support HTML or is blocking it purposely

My Link Here <http://www.example.com>

--000000000000f3b2130570186a0c
Content-Type: text/html; charset="UTF-8"

<div dir="ltr">
<div>This is my HTML version of the email</div>
<div><br></div>
<div><a href="http://www.example.com">My Link Here</a><br></div>
</div>

--000000000000f3b2130570186a0c--
--000000000000f3b2150570186a0e
Content-Type: text/csv; charset="US-ASCII"; name="test.csv"
Content-Disposition: attachment; filename="test.csv"
Content-Transfer-Encoding: base64
X-Attachment-Id: f_jj5qmzqz0

The boundaries define multipart segments.

边界定义了多部分段。

The boundary ID that has no dashes at the end is a start point of a segment.

末尾没有破折号的边界 ID 是线段的起点。

The one with the two dashes at the end is the end point.

末尾有两个破折号的那个是终点。

In this example, there's a subpart within the multipart/mixed main section, for multipart/alternative.

在这个例子中,multipart/mixed main 部分中有一个子部分,用于 multipart/alternative。

The multipart/alternative method basically says "Fallback to this, IF the priority part does not succeed" - in this example HTML is taken as priority normally by email clients. If an email client won't display the HTML, it falls back to the plain text.

multipart/alternative 方法基本上是说“回退到这个,如果优先级部分不成功” - 在这个例子中,电子邮件客户端通常将 HTML 作为优先级。如果电子邮件客户端不显示 HTML,它会回退到纯文本。

The multipart/mixed method which encapsulates this whole message, is basically saying there's different content here, display both.

封装整个消息的 multipart/mixed 方法基本上是说这里有不同的内容,同时显示两者。

In this example, I placed a CSV file attachment on the email. You'll see the attachment get plugged in using base64 in the command below.

在本例中,我在电子邮件中放置了一个 CSV 文件附件。您将在下面的命令中看到使用 base64 插入附件。

I threw in the attachment as an example, you'll have to set your content type appropriately for your attachment and specify whether inline or not.

我以附件为例,您必须为附件适当设置内容类型,并指定是否内联。

The X-Attachment-Id is necessary for some providers, randomize the ID you set.

某些提供程序需要 X-Attachment-Id,随机化您设置的 ID。

The command to mail this is:

邮寄这个命令是:

echo -e "`cat test.txt; openssl base64 -e < test.csv`\n--000000000000f3b2150570186a0e--\n" | mailx -s "Test 2 $( echo -e "\nContent-Type: multipart/mixed; boundary=\"000000000000f3b2150570186a0e\"" )" -r [email protected] [email protected]

As you can see in the mailx Subject line I insert the multipart boundary statically, this is the first header the email client will see.

正如您在 mailx 主题行中看到的,我静态插入了多部分边界,这是电子邮件客户端将看到的第一个标头。

Then comes the test.txt contents being dumped.

然后是 test.txt 内容被转储。

Regarding the attachment, I use openssl (which is pretty standard on systems) to convert the file attachment to base64.

关于附件,我使用 openssl(系统上非常标准)将文件附件转换为 base64。

Additionally, I added the boundary close statement at the end of this echo, to signify the end of the message.

此外,我在此回声的末尾添加了边界关闭语句,以表示消息的结束。

This works around heirloom-mailx problems and is virtually script-less.

这可以解决传家宝mailx 问题,并且几乎不需要脚本。

The echo can be a feed instead, or any other number of methods.

回声可以是一个提要,也可以是任何其他数量的方法。