[html] Sending HTML mail using a shell script

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

This question is related to html linux email bash sendmail

The answer is


You can use the option -o in sendEmail to send a html email.

-o message-content-type=html to specify the content type of the email.

-o message-file to add the html file to the email content.

I have tried this option in a shell scripts, and it works.

Here is the full command:

/usr/local/bin/sendEmail -f [email protected] -t "[email protected]" -s \
 smtp.test.com -u "Title" -xu [email protected] -xp password \
 -o message-charset=UTF-8  \
 -o message-content-type=html \
 -o message-file=test.html

The question asked specifically on shell script and the question tag mentioning only about sendmail package. So, if someone is looking for this, here is the simple script with sendmail usage that is working for me on CentOS 8:

#!/bin/sh
TOEMAIL="[email protected]"
REPORT_FILE_HTML="$REPORT_FILE.html"
echo "Subject: EMAIL SUBJECT" >> "${REPORT_FILE_HTML}"
echo "MIME-Version: 1.0" >> "${REPORT_FILE_HTML}"
echo "Content-Type: text/html" >> "${REPORT_FILE_HTML}"
echo "<html>" >> "${REPORT_FILE_HTML}"
echo "<head>" >> "${REPORT_FILE_HTML}"
echo "<title>Best practice to include title to view online email</title>" >> "${REPORT_FILE_HTML}"
echo "</head>" >> "${REPORT_FILE_HTML}"
echo "<body>" >> "${REPORT_FILE_HTML}"
echo "<p>Hello there, you can put email html body here</p>" >> "${REPORT_FILE_HTML}"
echo "</body>" >> "${REPORT_FILE_HTML}"
echo "</html>" >> "${REPORT_FILE_HTML}"

sendmail $TOEMAIL < $REPORT_FILE_HTML

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")" [email protected] < mytest.html

  1. Use mutt

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


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

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.


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: [email protected]" $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 [email protected] test.doc

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

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.


I've been trying to just make a simple bash script that emails out html formatted content-type and all these are great but I don't want to be creating local files on the filesystem to be passing into the script and also on our version of mailx(12.5+) the -a parameter for mail doesn't work anymore since it adds an attachment and I couldn't find any replacement parameter for additional headers so the easiest way for me was to use sendmail.

Below is the simplest 1 liner I created to run in our bash script that works for us. It just basically passes the Content-Type: text/html, subject, and the body and works.

printf "Content-Type: text/html\nSubject: Test Email\nHTML BODY<b>test bold</b>" | sendmail <Email Address To>

If you wanted to create an entire html page from a variable an alternative method I used in the bash script was to pass the variable as below.

emailBody="From: <Email Address From>
Subject: Test
Content-Type: text/html; charset=\"us-ascii\"
<html>
<body>
body
<b> test bold</b>

</body>
</html>
"
echo "$emailBody" | sendmail <Email Address To>

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

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:

#!/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\""

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 [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:

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.


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

(
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:

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

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: [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


Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to linux

grep's at sign caught as whitespace How to prevent Google Colab from disconnecting? "E: Unable to locate package python-pip" on Ubuntu 18.04 How to upgrade Python version to 3.7? Install Qt on Ubuntu Get first line of a shell command's output Cannot connect to the Docker daemon at unix:/var/run/docker.sock. Is the docker daemon running? Run bash command on jenkins pipeline How to uninstall an older PHP version from centOS7 How to update-alternatives to Python 3 without breaking apt?

Examples related to email

Monitoring the Full Disclosure mailinglist require(vendor/autoload.php): failed to open stream Failed to authenticate on SMTP server error using gmail Expected response code 220 but got code "", with message "" in Laravel How to to send mail using gmail in Laravel? Laravel Mail::send() sending to multiple to or bcc addresses Getting "The remote certificate is invalid according to the validation procedure" when SMTP server has a valid certificate How to validate an e-mail address in swift? PHP mail function doesn't complete sending of e-mail How to validate email id in angularJs using ng-pattern

Examples related to bash

Comparing a variable with a string python not working when redirecting from bash script Zipping a file in bash fails How do I prevent Conda from activating the base environment by default? Get first line of a shell command's output Fixing a systemd service 203/EXEC failure (no such file or directory) /bin/sh: apt-get: not found VSCode Change Default Terminal Run bash command on jenkins pipeline How to check if the docker engine and a docker container are running? How to switch Python versions in Terminal?

Examples related to sendmail

Send mail via CMD console Relay access denied on sending mail, Other domain outside of network Using sendmail from bash script for multiple recipients sendmail: how to configure sendmail on ubuntu? VBScript to send email without running Outlook Send SMTP email using System.Net.Mail via Exchange Online (Office 365) Sending a mail from a linux shell script Sending HTML mail using a shell script Debugging PHP Mail() and/or PHPMailer How to send a html email with the bash command "sendmail"?