Sending HTML mail using a shell script

2019-01-07 06:39发布

问题:

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

回答1:

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 mail command:

body = '...'

echo $body | mail \
-a "From: me@example.com" \
-a "MIME-Version: 1.0" \
-a "Content-Type: text/html" \
-s "This is the subject" \
you@example.com

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.

Update

A shell script is basically a text file with Unix line endings that starts with a line called shebang that 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:

#!/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:

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

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



回答2:

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

(
echo "From: me@xyz.com "
echo "To: them@xyz.com "
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:

mutt -e 'set content_type="text/html"' me@mydomain.com -s "subject" <  message.html


回答3:

So far I have found two quick ways in cmd linux

  1. Use old school mail

mail -s "$(echo -e "This is Subject\nContent-Type: text/html")" test@yahoo.com < mytest.html

  1. Use mutt

mutt -e "my_hdr Content-Type: text/html" test@yahoo.com -s "subject" < mytest.html



回答4:

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.



回答5:

Another option is using msmtp.

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

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

Then just call:

(echo "Subject: <subject>"; echo; echo "<message>") | msmtp <email@domain.tld>

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:

From: sender@domain.tld
To: email@domain.tld
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@domain.tld

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



回答6:

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

Command

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

cpu_alert.html file sample.

From: donotreply@example.com
To: admin@example.com
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



回答7:

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

scanuser@owncloud:~$ vi sendMailAboutNewDocuments.sh

mail -s "You have new mail" -a "Content-type: text/html" -a "From: sender@xxx.com" $1 << EOF
<html>
<body>
Neues Dokument: $2<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 recipient@xxx.com test.doc


回答8:

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.

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

test.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.

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.

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.

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

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.

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.

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 fromaddress@example.com toaddress@example.com

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.

Then comes the test.txt contents being dumped.

Regarding the attachment, I use openssl (which is pretty standard on systems) to convert the file attachment to 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.

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



回答9:

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


回答10:

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

mail person@email.com -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:

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