mail -s "subject" [email protected] <test.html
works, but only for plain text email.
What is the correct way to send HTML email using the Linux command mail
?
9 Answers 9
There are many different versions of mail
around. When you go beyond mail -s subject to1@address1 to2@address2 <body
(for sending, that's all POSIX guarantees — and even -s
didn't exist in the old days), they tend to have different command line options. Adding an additional header isn't always easy.
With some
mailx
implementations, e.g. frommailutils
on Ubuntu or Debian'sbsd-mailx
, it's easy, because there's an option for that.mailx -a 'Content-Type: text/html' -s "Subject" to@address <test.html
With the Heirloom
mailx
, there's no convenient way. One possibility to insert arbitrary headers is to seteditheaders=1
and use an external editor (which can be a script).## Prepare a temporary script that will serve as an editor. ## This script will be passed to ed. temp_script=$(mktemp) cat <<'EOF' >>"$temp_script" 1a Content-Type: text/html . $r test.html w q EOF ## Call mailx, and tell it to invoke the editor script EDITOR="ed -s $temp_script" heirloom-mailx -S editheaders=1 -s "Subject" to@address <<EOF ~e . EOF rm -f "$temp_script"
With a general POSIX
mailx
, I don't know how to get at headers.
If you're going to use any mail
or mailx
, keep in mind that
- This isn't portable even within a given Linux distribution. For example, both Ubuntu and Debian have several alternatives for
mail
andmailx
. - When composing a message,
mail
andmailx
treats lines beginning with~
as commands. If you pipe text intomail
, you need to arrange for this text not to contain lines beginning with~
.
If you're going to install software anyway, you might as well install something more predictable than mail
/Mail
/mailx
. For example, mutt. With Mutt, you can supply most headers in the input with the -H
option, but not Content-Type
, which needs to be set via a mutt option.
mutt -e 'set content_type=text/html' -s 'hello' 'to@address' <test.html
Or you can invoke sendmail
directly. There are several versions of sendmail
out there, but they all support sendmail -t
to send a mail in the simplest fashion, reading the list of recipients from the mail. (I think they don't all support Bcc:
.) On most systems, sendmail
isn't in the usual $PATH
, it's in /usr/sbin
or /usr/lib
.
cat <<'EOF' - test.html | /usr/sbin/sendmail -t
To: to@address
Subject: hello
Content-Type: text/html
EOF
-
Tried using the mutt example above; substituting real values for the filename, to email address, etc. but got "No recipients were specified" I'm very new to mutt, @Gilles do you know why that might have happened? (osx mountain lion, mutt 1.5.21 installed via homebrew)Chuck van der Linden– Chuck van der Linden2013年07月15日 16:58:02 +00:00Commented Jul 15, 2013 at 16:58
-
my second line was "To: [email protected]" (sorry for lack of formatting, not possible in a response, actual text was sans quotes) and I included a blank line before putting in the EOF. would there be configuration I need to do to mutt? prior to trying the example you gave (with proper values substituted) all I did was 'brew install mutt'Chuck van der Linden– Chuck van der Linden2013年07月15日 19:10:30 +00:00Commented Jul 15, 2013 at 19:10
-
@ChuckvanderLinden Ask a new question. Copy-paste the exact command you ran and the full error message. See if you can send an email from mutt using the interactive interface.Gilles 'SO- stop being evil'– Gilles 'SO- stop being evil'2013年07月15日 19:15:17 +00:00Commented Jul 15, 2013 at 19:15
-
I was able to send something via the 'interactive' interface, it initially complained about a mail directory missing and offered to create it. reminded how much I hate vim ;-) but got it to send. I'll start a new question as that is easier to format etc. The exact error message was just what I said "No recipients were specified."Chuck van der Linden– Chuck van der Linden2013年07月15日 19:45:50 +00:00Commented Jul 15, 2013 at 19:45
-
New question unix.stackexchange.com/questions/83137/…Chuck van der Linden– Chuck van der Linden2013年07月15日 20:06:58 +00:00Commented Jul 15, 2013 at 20:06
#!/bin/sh
(
echo "To: [email protected]"
echo "Subject: hello"
echo "Content-Type: text/html"
echo
echo "<html><b><font size='7'>H</font>ello</b></html>"
echo
) | /usr/sbin/sendmail -t
-
7That doesn't acually use
mail
.user16144– user161442012年10月17日 19:09:27 +00:00Commented Oct 17, 2012 at 19:09 -
4@user16144 No, but it's a nice alternative that the OP might like to consider.trusktr– trusktr2014年02月12日 03:24:25 +00:00Commented Feb 12, 2014 at 3:24
-
Yes, it does not use mail but it works everywhere I have tried it which is more than I can say for the other solutions.user1683793– user16837932018年05月03日 16:21:29 +00:00Commented May 3, 2018 at 16:21
-
Works beautifully on Mac as well.Asim Jalis– Asim Jalis2019年02月28日 20:41:41 +00:00Commented Feb 28, 2019 at 20:41
With the Heirloom mailx, convenient way is
mailx -s "$(echo -e "Newsletter issue 3\nContent-Type: text/html")" [email protected] < /tmp/htmlmail.txt
Thanks, Dude
Tested on Fedora 17, and worked
-
1Cheeky. I like it. :-]Alastair Irvine– Alastair Irvine2016年11月16日 16:29:49 +00:00Commented Nov 16, 2016 at 16:29
-
3Beware that this solution may lead to the email having both "Content-Type: text/html" and "Content-Type: text/plain", and potential inconsistencies if you use this way to specify charset.Skippy le Grand Gourou– Skippy le Grand Gourou2017年03月16日 15:45:22 +00:00Commented Mar 16, 2017 at 15:45
You will have to add Content-Type
header to your email to make this happen.
echo "<html><b>Hello</b></html>" | mail -a "Content-type: text/html;" -s "Testing" [email protected]
will work
-
3mail: illegal option -- apyth0ner– pyth0ner2011年06月22日 06:56:19 +00:00Commented Jun 22, 2011 at 6:56
-
Do you have
mailx
? That might have the option. If that doesn't work. If that doesn't work, you can consider using mutt although I don't know off hand what the command line switches to do it are.Noufal Ibrahim– Noufal Ibrahim2011年06月22日 07:04:50 +00:00Commented Jun 22, 2011 at 7:04 -
1if mail isn't cutting the mustard, use python ... docs.python.org/library/email-examples.html examples is the 3rd one or #6 which suits your requirement.sdolgy– sdolgy2011年06月22日 08:40:35 +00:00Commented Jun 22, 2011 at 8:40
-
Python will require you to write (and maintain) a script. A command line one liner has different advantages.Noufal Ibrahim– Noufal Ibrahim2011年06月22日 11:04:20 +00:00Commented Jun 22, 2011 at 11:04
-
I have mailx,but "option -a" don't work,still show:mail: illegal option -- apyth0ner– pyth0ner2011年06月27日 01:17:15 +00:00Commented Jun 27, 2011 at 1:17
With heirloom-mailx you can change sendmail program to your hook script, replace headers there and then use sendmail.
The script I use (~/bin/sendmail-mailx-hook
):
#!/bin/bash
sed '1,/^$/{
s,^\(Content-Type: \).*,ドル1円text/html; charset=utf-8,g
s,^\(Content-Transfer-Encoding: \).*,ドル18円bit,g
}' | sendmail $@
This script changes the values in the mail header as follows:
Content-Type:
totext/html; charset=utf-8
Content-Transfer-Encoding:
to8bit
(not sure if this is really needed).
To send HTML email:
mailx -Ssendmail='~/bin/sendmail-mailx-hook' -s "subject" [email protected] < test.html
This method is more effective than proposed by @Gilles because it does not create temporary files and just fix the stream on-the-fly.
I have used the below scripts to happen
#!/bin/ksh
(
echo "To: [email protected]"
echo "Subject: Job Status"
echo "Content-Type: text/html"
echo
echo "<html>
<head>
<title>Status of the jobs during the day</title>
<style>
table, th, td {
border: 1px solid blue;
border-collapse: collapse;
}
th, td {
padding: 5px;
}
</style>
</head>
<body>
<table style='width:100%'>
<tr bgcolor='#808080'>
<th>Job Name</th>
<th>System name</th>
<th>Status</th>
</tr>
<tr>
<td>Job-1</td>
<td>Sys</td>
<td>Sucess</td>
</tr>
<tr>
<td>Job-2</td>
<td>sys</td>
<td>Failure</td>
</tr>
<tr>
<td>Job-3</td>
<td>sys</td>
<td>Sucess</td>
</tr>
</table>
</body></html>"
echo
) | /usr/sbin/sendmail -t
-
Nothing here is specific to
ksh
; you could change the shebang to#!/bin/sh
. The path tosendmail
differs between platforms; probably take it out and rely on yourPATH
instead (and/or check in/usr/libexec
and some other peculiar places).tripleee– tripleee2022年11月03日 12:31:59 +00:00Commented Nov 3, 2022 at 12:31
For me i needed to specify a variable such as SMTP server, so the mail command worked in the below fashion. I searched across many posts, and i found below property to convert the body into text/html. Now the email i receive is in the HTML format.
Content-Disposition: inline
Unix version: Red Hat Enterprise Linux Server release 6.6 (Santiago)
First. Create whatever information is needed into a script (testSql.sh)
echo "<html><body><pre>"
mysql -u USERNAME -pPASSWORD -P PORTNUMBER -h HOSTNAME DBNAME --table -e "select columns from tablename where member in ('value1','value2')"
echo "</pre></body></html>"
Second. Pipe that script to the mail command
./testSql.sh | mail -v -S smtp=smtp://IP:PORTNUMBER -s "$(echo -e "This is the subject\nContent-Type: text/ht ml\nMIME-Version: 1.0\nContent-Disposition: inline")" [email protected]
By doing this i get information as below in the email:
Content-Disposition: inline Message-ID: User-Agent: Heirloom mailx 12.4 7/29/08 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Value1 Value2
Value1 and Value2 as per the HTML tagging done in the testSql.sh
-
i needed \r\n on my Centos-8edwardsmarkf– edwardsmarkf2021年01月12日 15:49:41 +00:00Commented Jan 12, 2021 at 15:49
Posted in another thread but basically on our version of mail/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 a simple 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>
cat htmlfile.html | mail -s "subject" [email protected]
-
5Nope. This will send a text email with HTML in the body.Noufal Ibrahim– Noufal Ibrahim2011年06月22日 06:35:06 +00:00Commented Jun 22, 2011 at 6:35
echo
andcat
, but for many real-world scenarios, you really really don't want to.