Bash Script – Sending Multiple Text Attachments via Mail Command

bashmail-commandshell-scriptsmtp

Running this script on: "Red Had Enterprise Linux Server release 5.11 (Tikanga)"

Mail is: version 8.1 6/6/93 (appears quite old).

Have tried various things and cannot seem to get this to work..

echo "Email message" | mail -a /home/user/checks/notprocessed.txt -a /home/user/checks/dirlist.txt -s "Subject" recipient@company.com /home/user/checks

Resulting message:

mail: invalid option — a

mutt is not installed and I have limited access to this system as it is owned by the company I work for. I could add in other components, but has to go through change management, and related processes.

uuencode is not available either.

Here is what I am using today and I am trying to add a second file to:

if grep 'Not Empty' /home/user/checks/notprocessed.txt
   then
   echo "files were found";

   SUBJECT="NIGHTLY DIRECTORY LISTING OF FILES SENT TO VENDOR";
   FROM="SENDER<sender@company.com>"
   # EMAIL="JOHN DOE<recipient@company.com>"
   EMAIL="MARY DOE<recipient@company.com>";
   /bin/mail -s "$SUBJECT" "$EMAIL" -- -f "$FROM" < /home/user/checks/notprocessed.txt /home/user/checks/dirlist.txt

   exit -20
fi

And.. /home/user/checks/dirlist.txt is not attached or included as part of the e-mail. I would like /home/user/checks/dirlist.txt to be actually an attachment

This actually does work – but includes the notprocessed.txt as the body of the email..

if grep 'Not Empty' /home/user/checks/notprocessed.txt
   then
   echo "files were found";

   SUBJECT="NIGHTLY DIRECTORY LISTING OF FILES SENT TO VENDOR";
   FROM="SENDER<sender@company.com>"
   # EMAIL="JOHN DOE<recipient@company.com>"
   EMAIL="MARY DOE<recipient@company.com>";
   /bin/mail -s "$SUBJECT" "$EMAIL" -- -f "$FROM" < /home/user/checks/notprocessed.txt

   exit -20
fi

Best Answer

Well, what happens when you do an stdin redirect (the <), is that the first file - and only the first - is opened and its content passed to mail's stdin which uses it as the body.

Because your mailx implementation is old, it does not support the current version's -a flag to create MIME attachments. What you can do instead is to create the MIME format yourself, using things that are available.

Fortunately its not hard to do using a simple bash script (which I'm 100% sure is available, even on RHEL 5 :-) ), something as simple as this would probably do:

#!/bin/bash
msgid="$RANDOM$RANDOM$RANDOM$RANDOM"
to="$1"
shift
subject="$1"
shift
echo "To: $to"
echo "From: secret-admirer@example.com"
echo "Subject: $subject"
echo "Message-ID: $msgid"
echo "MIME-Version: 1.0"
echo "Content-Type: multipart/mixed; boundary=$msgid"
echo "" # header termination
while [ -n "$1" ]; do 
    echo "--$msgid"
    echo "Content-Type: text/plain; charset=UTF-8"
    echo "Content-Disposition: attachment; filename=\"$(basename $1)\""
    echo "Content-Transfer-Encoding: base64"
    echo ""
    base64 < "$1"
    shift
done

Then you only need to submit the resulting email text to sendmail for delivery, something like this:

mail.sh "$SUBJECT" "$EMAIL" /home/user/checks/notprocessed.txt \
   /home/user/checks/dirlist.txt | sendmail -t

This script uses the base64 command to "ASCII armor" files, so you can send both text and binary files, though if you are not sending text files you probably want to figure out how to set the attachment's Content-type correctly (or just change it all to application/octet-stream, i.e. "binary"). That command is available as part of coreutils on RHEL 5, so I don't expect there to be and problem with using it.

Also note the use of the -t flag to sendmail to have the MTA just read the email envelope from the mail itself, so there's no need to put anything else in the sendmail command arguments. Just make sure that the script includes all the needed fields in the output - I've made it read the recipient and subject from the command line like mailx does, but its not necessary and the sender address is hard-coded anyway.

Related Question