shell script not sending mail accurately using SMTP server - linux

I wrote script to send mail automatically using an SMTP connection but when I execute the script, sometimes it works and sometimes it is not sending mail. Behavior is quite ambiguous.
Environment : Linux Server Fedora 14
Mailing Client : Lotus Notes 8.5.2
Please find script below.
# Function for sending email
sendemail(){
date=`date '+%d-%m-%Y'`
dbDir=/var/lib/MYSQLBACKUP/$date
dbname='DBNAME'
log_file="${dbDir}/${dbname}_${date}.log"
attached_file="${dbname}_${date}.log"
echo $log_file
echo $attached_file
encoded_log_file=`cat $log_file | openssl base64`
#echo $encoded_log_file
( echo open 172.40.201.31 25
sleep 8
echo helo 172.40.201.31
echo mail from:Pratik.Vyas#gmail.com
echo rcpt to:Pratik.Vyas#gmail.com
echo data
echo to:Pratik.Vyas#gmail.com
echo from:Pratik.Vyas#gmail.com
echo "subject: SPARC CQ DB Backup Report : $date :"
echo "MIME-Version: 1.0"
#echo "Content-Type: text/plain; charset=UTF-8"
#echo "Please view attached file"
echo "Content-Type: text/x-log;name="$attached_file""
echo "Content-Disposition:attachment;filename="$attached_file""
echo "Content-Transfer-Encoding: base64"
echo $encoded_log_file
echo $1
sleep 15
echo .
echo ^]
echo quit ) | telnet
echo "status:$?"
echo "Hello done"
}
sendemail

Here's a rewrite using /usr/lib/sendmail. This is not necessarily the correct location for your system, but you should be able to adapt it.
# Function for sending email
sendemail(){
date=$(date '+%d-%m-%Y') # prefer $(...) over `...`
dbDir=/var/lib/MYSQLBACKUP/$date
dbname='DBNAME'
log_file="${dbDir}/${dbname}_${date}.log"
attached_file="${dbname}_${date}.log"
echo $log_file
echo $attached_file
encoded_log_file=$(openssl base64 < "$log_file") # notice UUCA fix + quoting
#echo $encoded_log_file
# You should configure sendmail to use 172.40.201.31 as your smarthost
/usr/lib/sendmail -oi -t <<________HERE
to: Pratik.Vyas#gmail.com
from: Pratik.Vyas#gmail.com
subject: SPARC CQ DB Backup Report : $date :
MIME-Version: 1.0
Content-Type: text/x-log; name="$attached_file"
Content-Disposition: attachment; filename="$attached_file"
Content-Transfer-Encoding: base64
X-Ample: notice empty line between headers and body! # <-- look
$encoded_log_file
$1
________HERE
echo "status:$?"
echo "Hello done"
}
sendemail

I would recommend using a library or command line program (like mail or mailx) to send mail instead of trying to implement SMTP in a shell script.

Related

Sendmail command to send a file as an email body as well as attachment [duplicate]

This question already has answers here:
How do I send a file as an email attachment using Linux command line?
(25 answers)
Closed 4 years ago.
I want to send an email using sendmail command in bash. The email should get it's body by reading Input_file_HTML and it should send same input file as an attachment too. To do so I have tried the following.
sendmail_touser() {
cat - ${Input_file_HTML} << EOF | /usr/sbin/sendmail -oi -t
From: ${MAILFROM}
To: ${MAILTO}
Subject: $1
Content-Type: text/html; charset=us-ascii
cat ${Input_file_HTML}
Content-Transfer-Encoding: 7bit
MIME-Version: 1.0
Content-Disposition: attachment; filename: ${Input_file_HTML}
EOF
}
The above command is giving an email with only the attachment of Input_file_HTML and it is not writing it in the body of email. Could you please help/guide me on same? I am using outlook as the email client. I have even removed the cat command in above command, but it also is not working.
Use mutt instead?
echo "This is the message body" | mutt -a "/path/to/file.to.attach" -s "subject of message" -- recipient#domain.com
To install mutt on Debian systems:
sudo apt-get install -y mutt
EDIT Try this if you can only use sendmail:
sendmail_attachment() {
FROM="$1"
TO="$2"
SUBJECT="$3"
FILEPATH="$4"
CONTENTTYPE="$5"
(
echo "From: $FROM"
echo "To: $TO"
echo "MIME-Version: 1.0"
echo "Subject: $SUBJECT"
echo 'Content-Type: multipart/mixed; boundary="GvXjxJ+pjyke8COw"'
echo ""
echo "--GvXjxJ+pjyke8COw"
echo "Content-Type: text/html"
echo "Content-Disposition: inline"
echo "<p>Message contents</p>"
echo ""
echo "--GvXjxJ+pjyke8COw"
echo "Content-Type: $CONTENTTYPE"
echo "Content-Disposition: attachment; filename=$(basename $FILEPATH)"
echo ""
cat $FILEPATH
echo ""
) | /usr/sbin/sendmail -t
}
Use like this:
sendmail_attachment "to#example.com" "from#example.com" "Email subject" "/home/user/file.txt" "text/plain"

How to replace value of place holder

I am new to shell programming. I have two files:
eg.txt
file.sh
The eg.txt file has some HTML content and file.sh cotains a shell script.
In the script a value is assigned to the temp variable, and that value should be injected into the HTML file.
eg.txt
<html>
Hi MGM ,<br/>
One alert has been received !!<br/>
Here is the event Data.<br/><br/>
<font size=‘1’>{temp}</font>
<br/><br/>
Regards,
WDTS Supports.
</html>
file.sh
echo $1
temp=56
(
echo "To:"$1
echo "Subject: Alert Updates !! "
echo "Content-Type: text/html"
echo cat eg.txt
) | /usr/sbin/sendmail -t
echo "Mail sent !!"
With sed :
sed "s/{temp}/$temp/" eg.txt | /usr/sbin/sendmail -t
You can also use printf to inject variables in your template :
file.sh
temp=56
tpl=$(cat "eg.txt")
printf "$tpl" "$1" "$temp" | /usr/sbin/sendmail -t
eg.txt
To:%s
Subject: Alert Updates !!
Content-Type: text/html
<html>
Hi MGM ,<br/>
One alert has been received !!<br/>
Here is the event Data.<br/><br/>
<font size=‘1’>%s</font>
<br/><br/>
Regards,
WDTS Supports.
</html>
Update:
If multiple variables, just write multiple substitute commands (and update placeholders in eg.txt):
sed "s/{temp1}/$temp1/;s/{temp2}/$temp2/" eg.txt | /usr/sbin/sendmail -t
I have introduced some error checking to your code :
#!/bin/bash
temp=56
if [ -z "$1" ]
then
echo "Usage : ./file.sh user_name_to_mail to"
exit -1
else
if id "$1" >/dev/null 2>&1 #Check if user exists, suppress stdout, stderr
then
mail_header=$(echo -e "To: $1\nSubject: Alert Updates"'!!'"\nContent-Type: text/html\n")
mail_body=$(awk -v var="$temp" '{print gensub(/{temp}/,var,"g"$0)}' eg.txt)
echo -e "$mail_header\n$mail_body" | sendmail -t
else
echo -e "Sorry! Invalid User\n"
exit -1 # The error code is set to detect failure
fi
fi
To prevent the mails going to spam you need to have a valid SPF record for domain from which you're sending email. Check [ this ] for a starting point.
Note:
! is a special character to bash, it is used to refer to previous command. To work around this problem I have used ..Updates"'!!'"\nContent-Type...
Inside the single quotes the ! loses its special meaning.
Interesting reads :
What is an [ SPF ] record?
Open SPF [ documentation ] .
echo $1
temp=56
(
echo "To:"$1
echo "Subject: Alert Updates !! "
echo "Content-Type: text/html"
awk -F "" -v var=$temp '{gsub(/{temp}/,var,$0); print}' < eg.txt
) | /usr/sbin/sendmail -t
echo "Mail sent !!"
added awk to '|' where the temp is stored in awk variable : var which is later replaced
awk -F "" -v var=$temp '{gsub(/{temp}/,var,$0); print}'

Server patching email notification linux script

I need to create an email notification linux script which can be used in the server patching activity. I have created one script for the same but getting some errors. Can anyone please check what's the issue.
Script -
#email constants
export to_addresses=xyz#abc.com
auth_1_app_path=/export/home/apps/test1/dev1;
function sendServerPatchingSuccessMail()
{
printf "HI Team,\r\n\r\nServer patching activity has been done successfully.\r\n\r\nRequest eText DEV team to validate the server patching changes.\r\n\r\nTotal time taken = $(( ($end_date-$start_date) / ( 60) )) minutes.\r\n\r\nRegards,\r\nAdmin\r\n\r\nNote: This is an auto generated mail, please do not reply. " | mail -s "server patching activity is done sucessfully." $to_addresses -c $cc_addresses
}
function sendServerPatchingStartMail()
{
printf "Hi Team,\r\n\r\nServer patching activity has started at $start_date.\r\n\r\nRequest eText DEV team to validate the server patching changes once they receive the server patching success mail.\r\n\r\nRegards,\r\nAdmin\r\n\r\nNote: This is an auto generated mail, please do not reply. " | mail -s "server patching activity has started." $to_addresses -c $cc_addresses
}
#define list of hosts as array
servers_array=( bookvm04 #DEV1
);
function doWork() {
start_date=$(date +%Y%m%d%H%M%S);
sendServerPatchingStartMail
#stop tomcat on all hosts
echo "`date "+%Y-%m-%d %H:%M:%S"` Stop tomcat stop."
#start for each host
for i in "${servers_array[#]}"
do
export ssh_to_remote_host="ssh -l bookweb -i /export/home/apps/bookplus/.ssh/id_dsa "
case $i in
#DEV1 Book Server
b3bookvm05)
app_path=$view_1_app_path;
;;
#DEV1 Book Server
b3bookvm04)
app_path=$auth_1_app_path;
;;
*) echo "`date "+%Y-%m-%d %H:%M:%S"` $i is not a valid option exiting"
exit 0;;
esac #end case
$ssh_to_remote_host $i $app_path/scripts/stopremote
if [ "$?" -ne 0 ]
then
echo "`date "+%Y-%m-%d %H:%M:%S"` node ${i} could not be stopped"
exit 0
fi
end_date=$(date +%Y%m%d%H%M%S);
echo "`date "+%Y-%m-%d %H:%M:%S"` Total time taken = $(( ($end_date- $start_date) / ( 60) )) minutes";
sendServerPatchingSuccessMail
}
Error while executing above script
-bash-4.1$ sh server_patching_alert.sh
: command not foundrt.sh: line 4:
: command not foundrt.sh: line 5:
: command not foundrt.sh: line 9:
: command not foundrt.sh: line 13:
'erver_patching_alert.sh: line 14: syntax error near unexpected token `
'erver_patching_alert.sh: line 14: `function sendServerPatchingSuccessMail()
This script is working fine.
server_array=$(hostname)
function sendServerPatchingSuccessMail()
{
# Set email constants
to_addresses=
cc_addresses=
# Send server patching completion mail
printf "mail body - server patching activity for hostname '$server_array' has been completed successfully" | mail -s "mail subject" -c $cc_addresses $to_addresses
}
sendServerPatchingSuccessMail

Mutt: sending html-formatted e-mail with an attachment

I have a requirement like, i need to export the sql query result set to a .csv file and send it as an attachment. but here i need to include the body with html formatting and wanted to include sample rows of the .csv file in body as well in html format.
csv file contains :
Id ID_CNT
a 3
b 6
and i want to display the mail body with sample rows.
I have tried below two ways
mutt -e "set content_type=text/html" -a query_gen23.csv -s "abc" abc#gmail.com
export CONTENT="test.html"
export SUBJECT="$subject"
#(
# echo "To: "
# echo "Subject: $SUBJECT"
# echo "MIME-Version: 1.0"
# echo "Content-Type: text/html"
# echo "Content-Disposition: inline"
# cat $CONTENT
#) | /usr/sbin/sendmail $MAILTO
mutt -s "$subject" -a "$subject".csv -a test.html "$MAILTO" </dev/null
Thanks in Advance!
It's a long time since I had used mutt, but if I remember right, it expects the body of the mail from standard input. In your script, you input-redirect from /dev/null !
I would divide the task into two steps: One creates the body (HTML code with the CSV sample lines), and the second step pipes this file into mutt. I think this is much easier than trying to do everything at once.
Following works fine for me :
#!/usr/bin/ksh
export MAILTO="spam#ebay.com"
export SUBJECT="Mail Subject"
export BODY="/tmp/email_body.html"
export ATTACH="/tmp/attachment.txt"
(
echo "To: $MAILTO"
echo "Subject: $SUBJECT"
echo "MIME-Version: 1.0"
echo 'Content-Type: multipart/mixed; boundary="-q1w2e3r4t5"'
echo
echo '---q1w2e3r4t5'
echo "Content-Type: text/html"
echo "Content-Disposition: inline"
cat $BODY
echo '---q1w2e3r4t5'
echo 'Content-Type: application; name="'$(basename $ATTACH)'"'
echo "Content-Transfer-Encoding: base64"
echo 'Content-Disposition: attachment; filename="'$(basename $ATTACH)'"'
uuencode -m $ATTACH $(basename $ATTACH)
echo '---q1w2e3r4t5--'
) | /usr/sbin/sendmail $MAILTO

Shell script to send email [duplicate]

This question already has answers here:
Sending a mail from a linux shell script
(11 answers)
Closed 5 years ago.
I am on linux machine and I monitor a process usage. Most of the time I will be away from my system and I have access to internet on my device. So I planned to write a shell-script that can mail me the output of the process.
Is it possible?
If so how to make a shell-script send me mail?
Please provide a snippet to get started.
Yes it works fine and is commonly used:
$ echo "hello world" | mail -s "a subject" someone#somewhere.com
Basically there's a program to accomplish that, called "mail". The subject of the email can be specified with a -s and a list of address with -t. You can write the text on your own with the echo command:
echo "This will go into the body of the mail." | mail -s "Hello world" you#youremail.com
or get it from other files too:
mail -s "Hello world" you#youremailid.com < /home/calvin/application.log
mail doesn't support the sending of attachments, but Mutt does:
echo "Sending an attachment." | mutt -a file.zip -s "attachment" target#email.com
Note that Mutt's much more complete than mail.
You can find better explanation here
PS: thanks to #slhck who pointed out that my previous answer was awful. ;)
sendmail works for me on the mac (10.6.8)
echo "Hello" | sendmail -f my#email.com my#email.com
mail -s "Your Subject" your#email.com < /file/with/mail/content
(/file/with/mail/content should be a plaintext file, not a file attachment or an image, etc)
#!/bin/sh
#set -x
LANG=fr_FR
# ARG
FROM="foo#bar.com"
TO="foo#bar.com"
SUBJECT="test é"
MSG="BODY éé"
FILES="fic1.pdf fic2.pdf"
# http://fr.wikipedia.org/wiki/Multipurpose_Internet_Mail_Extensions
SUB_CHARSET=$(echo ${SUBJECT} | file -bi - | cut -d"=" -f2)
SUB_B64=$(echo ${SUBJECT} | uuencode --base64 - | tail -n+2 | head -n+1)
NB_FILES=$(echo ${FILES} | wc -w)
NB=0
cat <<EOF | /usr/sbin/sendmail -t
From: ${FROM}
To: ${TO}
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=frontier
Subject: =?${SUB_CHARSET}?B?${SUB_B64}?=
--frontier
Content-Type: $(echo ${MSG} | file -bi -)
Content-Transfer-Encoding: 7bit
${MSG}
$(test $NB_FILES -eq 0 && echo "--frontier--" || echo "--frontier")
$(for file in ${FILES} ; do
let NB=${NB}+1
FILE_NAME="$(basename $file)"
echo "Content-Type: $(file -bi $file); name=\"${FILE_NAME}\""
echo "Content-Transfer-Encoding: base64"
echo "Content-Disposition: attachment; filename=\"${FILE_NAME}\""
#echo ""
uuencode --base64 ${file} ${FILE_NAME}
test ${NB} -eq ${NB_FILES} && echo "--frontier--" || echo
"--frontier"
done)
EOF
Well, the easiest solution would of course be to pipe the output into mail:
vs#lambda:~$ cat test.sh
sleep 3 && echo test | mail -s test your#address
vs#lambda:~$ nohup sh test.sh
nohup: ignoring input and appending output to `nohup.out'
I guess sh test.sh & will do just as fine normally.
top -b -n 1 | mail -s "any subject" your_email#domain.com

Resources