Link to home
Start Free TrialLog in
Avatar of Obi79
Obi79

asked on

Sending multiple email attachments using a shell script

Hi, I have a shell script that send an excel file as an email attachment.

I would like to be able to send more than one excel attachment at any given time.

This is the script that currently send one attachment.



#!/bin/ksh

if test ! -z "${5}"
then
echo ""
echo "Error:"
echo "                Too many arguments, try putting subject line in quotes."
echo ""
echo "                Usage:"
echo "                email-rep <filename> <recipient> <subject> <sender>"
echo ""
echo "                Subject and Sender are not mandatory."
exit 1
else

filepath="${1}"
filename=`basename "${filepath}"`
filextn=${filename##*.}
recipient="${2}"
subject="${3}"

if [ "${4}" = "" ]
 then
   sender="ABC  <abc@abc.com>"
 else  
sender="${4}"
fi

cat <<! | /usr/lib/sendmail -t -n
MIME-Version: 1.0
From:${sender}
To: ${recipient}
Subject: ${subject}
Content-Type: multipart/mixed; boundary="_boundarystring"

This is a multi-part message in MIME format.
--_boundarystring
Content-Transfer-Encoding: Base64
Content-Type: application/vnd.ms-excel
Content-Disposition: attachment; filename="${filename}"

`java base64 "${filepath}"`

--_boundarystring--
!
fi

My idea was to ask for the recipients email address then the arguments after that would be the files to be sent. Then use a for loop on the bit right after the "This is a multi-part ....", as this is the bit that needs to be typed out again for multiple attachments.


when I put the do loop in the code, it looked like this:

This is a multi-part message in MIME format.

for i in $3 $4 $5

do

filepath="$i"
filename=`basename "${filepath}"`

--_boundarystring
Content-Transfer-Encoding: Base64
Content-Type: application/vnd.ms-excel
Content-Disposition: attachment; filename="${filename}"


`java base64 "${filepath}"`

--_boundarystring

done

The program didn't seem to recognise the loop.
I am not very good at writing shell scripts and I literally just read up on loops today.
I would appreciate any suggestions or possible alternatives.

Thank you in advance.
Avatar of taus01
taus01
Flag of Germany image

The loop you made should work fine. I guess you put the loop between

cat <<! | /usr/lib/sendmail -t -n
... (your loop here?)
!

It won't work that way (unfortunately). I would suggest you create a temporary mail file and then pipe that file to sendmail. Also i would suggest not to use the java base64 encoder sine it does not support streaming and will most likely cause problems on big excel files. I have included a small perl base64 encoder that uses a buffer and should work on any filesize.

first the changes to your script:

...
#!/usr/bin/bash
#
# Create the Mail Header in temporary file (tmp.mail)
#
cat <<EOF >tmp.mail
MIME-Version: 1.0
From:${sender}
To: ${recipient}
Subject: ${subject}
Content-Type: multipart/mixed; boundary="_boundarystring"

This is a multi-part message in MIME format.
EOF

# Create Multipart attachments
#
for i in $3 $4 $5
do
filepath="$i"
filename=`basename "${filepath}"`
cat <<EOF >>tmp.mail

--_boundarystring
Content-Transfer-Encoding: Base64
Content-Type: application/vnd.ms-excel
Content-Disposition: attachment; filename="${filename}"

`base64.pl -filename="${filepath}"`

--_boundarystring
EOF
done

# Send the mail
#
`/usr/lib/sendmail -t -n <tmp.mail`


Here is the perl file to encode in base64 (I sure hope you got perl, if not you can use the java and hope the best):

#!/usr/local/bin/perl
# import module
use Getopt::Long;

# read options
$result = GetOptions ( "filename=s" => \$filename );  
     
use MIME::Base64 qw(encode_base64);
open(FILE, $filename) or die "$!";
while (read(FILE, $buf, 60*57)) {
    print encode_base64($buf);
}


I hope this helped, naturally you would like to add error handling and a dynamic loop depending on how many additional files the user specifies.

Sascha
ASKER CERTIFIED SOLUTION
Avatar of taus01
taus01
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Obi79
Obi79

ASKER

Hi Sascha,

the script works with the java base64. I just made a few ammendments and it works brilliantly. Thanks.
taus01,
That is a great script.  Exactly the starting point that I have been looking for also.  I have made a few customizations to fit what I need, and all is working well, one question though.  Whenever I send the mail I get two attachments for every one that I included, one of them is named something like ATT99711.txt and has no contents though mail email client reports it as being 78k.  Any ideas why this might be happening.
Hi,

Hard to say, but you can always check the tmp.mail file the script created to see what gets included, unless you modified the script to delete it :)

Sascha
I figured that one out, the closing "--_boundarystring" needs a " --" at the end like "--_boundarystring --".  

Now I have another question.  One of the attachments that I want to send is a text file.  The base64 encoding doesn't work properly with that.  From What I read online other places I need 7BIT encoding for that.  Any suggestions?

The file that I am sending looks like:
this is a test
line 2
line 3
line 4

The attachment that I recieve looks like:
this is a test line 2 line 3 line 4 n‹§uªò²Úâ
Avatar of tel2
I don't recall having to do special encoding for text files (but I used uuencode for all attachment types).  Apart from the rubbish at the end of the line, it looks as if the receiving system is Windows?, which prefers \n\r at the end of lines, rather than just \n as for UNIX.  Sound correct?  Want help with sorting it?
there is a easy way to send email with multiattachment.
#(echo " please check the attachments";uuecncode /path1/file1 file1;uuencode /path2/file2 file2) | mail -s "mail subject" abc@abc.com