HTML body and XLSX attachment in mail via UNIX using SENDMAIL command - unix

I am trying to send a mail via UNIX with HTML body and xlsx file as attachment, but I am not able to attach the file with the mail, can anybody share some sample code? This is what I have tried, I have to send the XLSX file as attachment for simplicity I am trying it with CSV,
Unix var file is a CSV file which contains data as abc,xyz#gmail.com
echo $file
while read LINE
do
echo $LINE;
fund_provider_code=`echo $LINE | awk -F',' '{print$1}'`
len=`echo $fund_provider_code | awk '{print length}'`
length=`expr $len + 2`
email_list=`echo $LINE | cut -c $length-`
echo fund_code=$fund_provider_code
email=$email_list
(BOUNDARY='=== This is the boundary between parts of the message. ==='
ATTACHMENT="$attachment_file"
SUBJECT="$subject_text"
VERSION=1.0
print - 'To:' ${email_list}
print - 'Subject:' ${SUBJECT}
print - 'MIME-Version: 1.0'
print - 'Content-Type: MULTIPART/MIXED; '
print - 'Content-Type: TEXT/HTML; charset=US-ASCII'
print -
awk -v message1="${msg1}" ' BEGIN {
print "<html><body>"
print "<style>"
print "p.MsoNormal, li.MsoNormal, div.MsoNormal \{mso-style-parent:\"\"; margin:0in; margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:12.0pt;font-family:\"Arial\"; mso-fareast-font-family:\"MSMincho\";\}"
print "</style>"
print "<div class=Section1>"
print "<p class=MsoNormal style=\"mso-layout-grid-align:none;text-autospace:none\"><span style=\"font-size:12.0pt;font-family:'Arial';mso-bidi-font-family:'Arial'; color:Black\">Dear All,<o:p></o:p></span></p>"
print "</div></body></html>"
}' email_body.txt;
print -
print - "--${BOUNDARY}--"
print - 'ATTACH="/projects/dit/edw/EDW_OUTBOUND_FEEDS/bin/email.csv"'
print - 'Content-Type: TEXT/HTML, multipart/mixed, text/html, application/octet-stream ; name=email.csv'
print - "Content-Transfer-Encoding: base64"
print - 'Content-Disposition: attachment; filename=abc.csv'
uuencode "/projects/dit/edw/EDW_OUTBOUND_FEEDS/bin/email.csv" email.csv
print -
print - "--${BOUNDARY}--"
) | sendmail ${email_list}
done < "$file"

It looks like you have a discrepancy in the filename you want to send. The below assume you want to send file locally defined as:
/projects/dit/edw/EDW_OUTBOUND_FEEDS/bin/email.csv
--- however, you hadn't defined it properly, so I fixed the assignment so:
ATTACH="/projects/dit/edw/EDW_OUTBOUND_FEEDS/bin/email.csv"
Or did you want to use ATTACHMENT? I think you must clean this code.
I found no use of this line:
ATTACHMENT="$attachment_file"
var subject_text isn't defined, or is it in a part of the script we don't see in your OP?
var attachment_file isn't defined either.
I think you should use the file you want to send in a var: $ATTACH
echo $file
while read LINE
do
echo $LINE;
fund_provider_code=`echo $LINE | awk -F',' '{print$1}'`
len=`echo $fund_provider_code | awk '{print length}'`
length=`expr $len + 2`
email_list=`echo $LINE | cut -c $length-`
echo fund_code=$fund_provider_code
email=$email_list
(BOUNDARY='=== This is the boundary between parts of the message. ==='
ATTACHMENT="$attachment_file"
ATTACH="/projects/dit/edw/EDW_OUTBOUND_FEEDS/bin/email.csv"
SUBJECT="$subject_text"
VERSION=1.0
print - 'To:' ${email_list}
print - 'Subject:' ${SUBJECT}
print - 'MIME-Version: 1.0'
print - 'Content-Type: MULTIPART/MIXED; '
print - 'Content-Type: TEXT/HTML; charset=US-ASCII'
print -
awk -v message1="${msg1}" ' BEGIN {
print "<html><body>"
print "<style>"
print "p.MsoNormal, li.MsoNormal, div.MsoNormal \{mso-style-parent:\"\"; margin:0in; margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:12.0pt;font-family:\"Arial\"; mso-fareast-font-family:\"MSMincho\";\}"
print "</style>"
print "<div class=Section1>"
print "<p class=MsoNormal style=\"mso-layout-grid-align:none;text-autospace:none\"><span style=\"font-size:12.0pt;font-family:'Arial';mso-bidi-font-family:'Arial'; color:Black\">Dear All,<o:p></o:p></span></p>"
print "</div></body></html>"
}' email_body.txt;
print -
print - "--${BOUNDARY}--"
print - 'ATTACH="${ATTACH}"'
print - 'Content-Type: TEXT/HTML, multipart/mixed, text/html, application/octet-stream ; name="'$(basename ${ATTACH})'"'
print - "Content-Transfer-Encoding: base64"
print - 'Content-Disposition: attachment; filename="'$(basename ${ATTACH})'"'
uuencode $ATTACH $(basename ${ATTACH})
print - "--${BOUNDARY}--"
) | sendmail ${email_list}
done < "$file"
From examples I saw, if you use GNU uuencode, you may need to replace the line
uuencode $ATTACH $(basename $ATTACH)
by
uuencode --base64 $ATTACH $(basename $ATTACH)

Related

Splitting a file in a shell script adds unwanted newlines

I need to process a long text file splitting it into many smaller files. I have a single pass while - read - done <inputfile loop and when a line is matched, that signals the start of new output file. The matched lines are always preceded by a newline character in the input file.
My problem is that the output files (except the final one) are extended by a newline character. I have recreated the problem in this short example.
#!/bin/zsh
rm inputfile outputfile1 outputfile2
IFS=''
printf "section1\nsection1end\n\nsection2\nsection2end\n" >inputfile
echo " open outputfile1"
exec 3<> outputfile1
counter=1
IFS=$'\n'
while IFS= read line; do
if [[ "$line" == "section2" ]]; then
echo " Matched start of section2. Close outputfile1 and open outputfile2"
exec 3>&-
exec 3<> outputfile2
fi
echo "$line" >&3
echo $counter $line
let "counter = $counter + 1"
done <inputfile
echo " Close outputfile2"
exec 3>&-
echo
unset IFS
echo `wc -l inputfile`
echo `wc -l outputfile1`
echo `wc -l outputfile2`
echo " The above should show 5, 2, 2 as desired number of newlines in these files."
Which outputs:
open outputfile1
1 section1
2 section1end
3
Matched start of section2. Close outputfile1 and open outputfile2
4 section2
5 section2end
Close outputfile2
5 inputfile
3 outputfile1
2 outputfile2
The above should show 5, 2, 2 as desired number of newlines in these files.
Option 1
Get rid of all empty lines. This only works if you don't need to retain any of the empty lines in the middle of a section.
Change:
echo "$line" >&3
To:
[[ -n "$line" ]] && echo "$line" >&3
Option 2
Rewrite each file using command substitution to trim any trailing newlines. Works best with short files. Change:
exec 3>&-
exec 3<> outputfile2
To:
exec 3>&-
data=$(<outputfile1)
echo "$data" >outputfile1
exec 3<> outputfile2
Option 3
Have the loop write the line from the prior iteration, and then do not write the final line from the prior file when you start a new file:
#!/bin/zsh
rm inputfile outputfile1 outputfile2
IFS=''
printf "section1\nsection1end\n\nsection2\nsection2end\n" >inputfile
echo " open outputfile1"
exec 3<> outputfile1
counter=1
IFS=$'\n'
priorLine=MARKER
while IFS= read line; do
if [[ "$line" == "section2" ]]; then
echo " Matched start of section2. Close outputfile1 and open outputfile2"
exec 3>&-
exec 3<> outputfile2
elif [[ "$priorLine" != MARKER ]]; then
echo "$priorLine" >&3
fi
echo $counter $line
let "counter = $counter + 1"
priorLine="$line"
done <inputfile
echo "$priorLine" >&3
echo " Close outputfile2"
exec 3>&-
echo
unset IFS
echo `wc -l inputfile`
echo `wc -l outputfile1`
echo `wc -l outputfile2`
echo " The above should show 5, 2, 2 as desired number of newlines in these files."

sendmail with zip is corrupting first file in the zip

I am trying to send a mail with zip file attached from an unix box. I am limited to use sendmail utility. i ziped the files using the command
zip test.zip 1.html 2.html 3.html
and when trying to send mail with below commands. One of the three files (first file) is not opening properly. but the rest 2.html and 3.html is working fine.
I am getting the error as "Unavailable Data: 1.html"
(
echo "From: from#from.com"
echo "To: to#to.com"
echo "Subject: subject"
echo "Mime-Version: 1.0"
echo 'Content-Type: multipart/mixed; boundary="X12345"'
echo '--X12345'
echo "Content-Type: application/zip;"
echo "Content-Transfer-Encoding: base64"
echo "Content-Disposition: attachement; filename=test.zip"
base64 test.zip
echo '--X12345'
) | sendmail -t
Can some please help. Thanks in advance.
You failed to provide empty line to mark end of main headers and end of mime part header.
(
cat - <<END
From: from#from.com
To: to#to.com
ubject: subject
Mime-Version: 1.0
Content-Type: multipart/mixed; boundary="X12345"
--X12345
Content-Type: application/zip;
Content-Transfer-Encoding: base64
Content-Disposition: attachement; filename=test.zip
END
base64 test.zip
echo '--X12345'
) | /usr/sbin/sendmail -t

send email with attachment using Unix

I am using the following script to send an email from Unix sever. I have a requirement to attach a file which is at the same location where script is available - /home/app111/attachment.csv.
Could you please help me how to send the file in attachment?
`CUR_DATE=`date +%Y/%m/%d`
echo $CUR_DATE
awk ' BEGIN {
print "To: XXXX#gmail.com"
print "From: YYYY#gmail.com"
print "MIME-Version: 1.0"
print "Content-Type: text/html"
print "Subject: PO file '$CUR_DATE'"
print "<html><body><font face="Times New Roman" size="10">Hi All,<br></br>
<br>Please load the attached PO file</br><br/>"
print "<br>Thanks,</br></font></body></html>"
} ' | sendmail -t`
1
Using mailx -a if mailx -a feature is supported
2
Using uuencode filenm filenm | mailx s#abc.com
3
mutt -a filenm a#abc.com
If you really want to use sendmail (and not mail or mutt), you'll have to encode your attachment in base64 and concatenate it to your message, along with boundaries and the whole nine yards. There is a great article describing exactly what you want to do here with a code example:
http://backreference.org/2013/05/22/send-email-with-attachments-from-script-or-command-line/
If you're on a flavor of Unix or Linux that has mutt or mail, I would definitely recommend one of the two instead of sendmail as it will be a lot easier (and these solutions are also described in the posted article). Here is an example of how you could do it with mail:
CUR_DATE=`date +%Y/%m/%d`
echo $CUR_DATE
to="XXXX#gmail.com"
from="YYYY#gmail.com"
content_type="text/html"
file_to_attach="/home/app111/attachment.csv"
subject="PO file '$CUR_DATE'"
read -r -d '' body << 'EOF'
<html><body><font face="Times New Roman" size="10">Hi All,<br></br>
<br>Please load the attached PO file</br><br/>
<br>Thanks,</br></font></body></html>
EOF
mail -A "$file_to_attach" --content-type "$content_type" -s "$subject" -r "$from" "$to" <<< "$body"
Try this:
MAILFROM="YYYY#gmail.com"
MAILTO="XXXX#gmail.com"
SUBJECT="PO file '$CUR_DATE'"
MAILPART_BODY=q1w2e3r4t5 ## Generates Unique ID
MAILPART=q1qw2ew3r4t35 ## Generates Unique ID
ATTACH="/home/app111/attachment.csv"
(
echo "From: $MAILFROM"
echo "To: $MAILTO"
echo "Subject: $SUBJECT"
echo "MIME-Version: 1.0"
echo "Content-Type: multipart/mixed; boundary=\"$MAILPART\""
echo ""
echo "--$MAILPART"
echo "Content-Type: multipart/alternative; boundary=\"$MAILPART_BODY\""
echo ""
echo "--$MAILPART_BODY"
echo "Content-Type: text/plain; charset=ISO-8859-1"
echo "You need to enable HTML option for email"
echo "--$MAILPART_BODY"
echo "Content-Type: text/html; charset=ISO-8859-1"
echo "Content-Disposition: inline"
echo "<html><body><font face="Times New Roman" size="10">Hi All,<br></br>
<br>Please load the attached PO file</br><br/>"
echo "<br>Thanks,</br></font></body></html>"
echo "--$MAILPART_BODY--"
echo "--$MAILPART"
echo 'Content-Type: application/pdf; name="'$(basename $ATTACH)'"'
echo "Content-Transfer-Encoding: uuencode"
echo 'Content-Disposition: attachment; filename="'$(basename $ATTACH)'"'
echo ""
uuencode $ATTACH $(basename $ATTACH)
echo "--$MAILPART--"
) | sendmail -t

echo does not display proper output

Following code read the test.txt contents and based on first field it redirect third field to result.txt
src_fld=s1
type=11
Logic_File=`cat /home/script/test.txt`
printf '%s\n' "$Logic_File" |
{
while IFS=',' read -r line
do
fld1=`echo $line | cut -d ',' -f 1`
if [[ $type -eq $fld1 ]];then
query=`echo $line | cut -d ',' -f 3-`
echo $query >> /home/stg/result.txt
fi
done
}
Following is the contents of test.txt:
6,STRING TO DECIMAL WITHOUT DEFAULT,cast($src_fld as DECIMAL(15,2) $tgt_fld
7,STRING TO INTERGER WITHOUT DEFAULT,cast($src_fld as integer) $tgt_fld
11,DEFAULT NO RULE,$src_fld
everything works fine except output in result.txt is $src_fld instead of s1. Can anyone please tell me what is wrong in the code?
Try replacing the below line
echo $query >> /home/stg/result.txt
with this one
eval "echo $query" >> /home/stg/result.txt

How to send HTML body email with multiple text attachments using sendmail

I want to send a HTML file as message body and want to attach multiple text files to this email message.
Since html file needs to be sent, sendmail has to be used ( I could not do it using mailx ).
How do you send HTML body email and multiple text attachments using sendmail?
Assuming you have uunecode available in your system you can send email with multiple attachments like this:
#!/bin/bash
...
...
...
BOUNDARY="=== This is the boundary between parts of the message. ==="
{
echo "From: $MAILFROM"
echo "To: $MAILTO"
echo "Subject:" $SUBJECT
echo "MIME-Version: 1.0"
echo "Content-Type: MULTIPART/MIXED; "
echo " BOUNDARY="\"$BOUNDARY\"
echo
echo " This message is in MIME format. But if you can see this,"
echo " you aren't using a MIME aware mail program. You shouldn't "
echo " have too many problems because this message is entirely in"
echo " ASCII and is designed to be somewhat readable with old "
echo " mail software."
echo
echo "--${BOUNDARY}"
echo "Content-Type: TEXT/PLAIN; charset=US-ASCII"
echo
echo "This email comes with multiple attachments."
echo
echo
echo "--${BOUNDARY}"
echo "Content-Type: application/zip; charset=US-ASCII; name="${ZIPFILE}
echo "Content-Disposition: attachment; filename="`basename ${ZIPFILE}`
echo
uuencode $ZIPFILE $ZIPFILE
echo
echo "--${BOUNDARY}--"
echo "Content-Type: application/pdf; charset=US-ASCII; name="${PDFFILE}
echo "Content-Disposition: attachment; filename="`basename ${PDFFILE}`
echo
uuencode $PDFFILE $PDFFILE
echo
echo "--${BOUNDARY}--"
} | /usr/lib/sendmail -t
I don't think sendmail is going to help you with that. Go for a client like mutt, and do e.g. mutt -a file1 -a file2 -- recipient#do.main. Or go for perl.
Here is a bash script I use to send reports I generate to people. They are sent as attachments. Place your HTML in the "body" variable of the script. I will leave the parametrization of the variables up to you.
#!/bin/bash
function get_mimetype(){
file --mime-type "$1" | sed 's/.*: //'
}
from="me.last#company.com"
to="some.one#companyBlah.com"
subject="Your Report my Lord"
boundary="=== Boundary ==="
body="The reports are attached to this email"
declare -a attachments
attachments=( "fileOne.out" "fileTwo.out" "fileThree.out" "file-et-cetera.out")
# Build headers
{
printf '%s\n' "From: $from
To: $to
Subject: $subject
Mime-Version: 1.0
Content-Type: multipart/mixed; boundary=\"$boundary\"
--${boundary}
Content-Type: text/plain; charset=\"US-ASCII\"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
$body
"
for file in "${attachments[#]}"; do
[ ! -f "$file" ] && echo "Attachment $file not found, omitting file" >&2 && continue
mimetype=$(get_mimetype "$file")
printf '%s\n' "--${boundary}
Content-Type: $mimetype
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=\"$file\"
"
base64 "$file"
echo
done
# print last boundary with closing --
printf '%s\n' "--${boundary}--"
} | sendmail -t -oi

Resources