2

I need to send contents of a file in an email and add some html note at the beginning and ending of the file. I have used "sendmail" for the purpose, however when I receive the email I do not see the line breaks in outlook causing the trouble. I have tried using the "mail" command but not sure how to add HTML notes to it. Here is the snippet I have:

open(my $sendmail,"|/usr/sbin/sendmail -t");
print $sendmail "From: linux\@test.com\n";
print $sendmail "To: kris\@test.com\n";
print $sendmail "Content-Type: text/html\n";
print $sendmail "Subject: My Test\n";
print $sendmail "\n";
my $Header = << 'END';
    <html>
            <head>
                    <h3><font color="red">For test</font></h3>
            </head>
            <body>
                    <h3><font color="red">For test</font></h3>
                    <br/>
            </body>
    </html>
END


print $sendmail $Header;    
print $sendmail "<br>Ran for time:  \n";
my $alert3 = `/bin/cat /home/kris/test.txt`;
print $sendmail $alert3;


close($sendmail);

while this works just fine to send the email, the contents of the file in "alert3" come in one single line vs several when you do cat. I also changed line break options in outlook with no luck. Is there any better way to handle these situations?

1

|/usr/sbin/sendmail -t will truncate messages if . is ever written as a line, among other problems. Also there is a distinct lack of error checking and other problems (open can fail, forking out to cat is a most expensive and complicated and error prone way to read the contents of a file).

With modern perl, one might instead use Email::Stuffer which greatly simplifies the task of properly constructing valid MIME parts via Email::MIME. Let's install that...

$ cpanm Email::Stuffer
...
12 distributions installed
$ 

I have App::cpanminus and local::lib setup; there are other ways to wrangle modules if need be, such as vendor packages, Carton, or so forth.

Now, the sending code will instead look something like

#!/usr/bin/env perl
use strict;
use warnings;

use Email::Stuffer;

my $the_html = <<'END';
<html><body><h3><font color="red">test</font></h3><br/></body></html>
END

Email::Stuffer
  ->from('linux@test.com')
  ->to('kris@test.com')
  ->subject('test test')
  ->html_body($the_html)
  ->attach_file('/home/kris/test.txt')
  ->send;

If the contents /home/kris/test.txt actually needs to be mixed into the middle of the HTML and not attached as a distinct file then the HTML related code might instead look something like (yep, more modules...)

use Email::Stuffer;
use File::Slurper 'read_text';

my $the_html = <<'HEAD';
<html><body><h3><font color="red">test</font></h3><br/>
HEAD

$the_html .= read_text('/home/kris/test.txt');

$the_html .= <<'TAIL';
</body></html>
TAIL

Email::Stuffer
  ->from('linux@test.com')
  ->to('kris@test.com')
  ->subject('test test')
  ->html_body($the_html)
  ->send;

though there are HTML template modules that can include files among other features if you want something more than sticking strings together and hoping the HTML works out.

0

This is going to be outlook's rendering ignoring the breaks rather than your script not sending them, but I doubt outlook's behavior can really be faulted here: html ignores line breaks, and you've got your content marked as html. Use the proper Multipurpose Internet Mail Extensions markup for a multipart mail message. Here's the sample from the linked page:

As a very simple example, the following multipart message has two parts, both of them plain text, one of them explicitly typed and one of them implicitly typed:

 From: Nathaniel Borenstein <nsb@bellcore.com> 
 To:  Ned Freed <ned@innosoft.com> 
 Subject: Sample message 
 MIME-Version: 1.0 
 Content-type: multipart/mixed; boundary="simple 
 boundary" 

 This is the preamble.  It is to be ignored, though it 
 is a handy place for mail composers to include an 
 explanatory note to non-MIME compliant readers. 
 --simple boundary 

 This is implicitly typed plain ASCII text. 
 It does NOT end with a linebreak. 
 --simple boundary 
 Content-type: text/plain; charset=us-ascii 

 This is explicitly typed plain ASCII text. 
 It DOES end with a linebreak. 

 --simple boundary-- 
 This is the epilogue.  It is also to be ignored.

The use of a Content-Type of multipart in a body part within another multipart entity is explicitly allowed. In such cases, for obvious reasons, care must be taken to ensure that each nested multipart entity must use a different boundary delimiter. See Appendix C for an example of nested multipart entities.

so put the html parts in text/html parts, the plain text in text/plain parts.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.