Multiple attachments using mutt

I am trying to attach multiple files using mutt command, and all file names to be attached are taken from a flat file. and mutt command is called from a bash script when :

  1. Script execution is completed.
  2. Script execution is interrupted for some reason.

-------------------------------------------------------------------

Contents of REPORTS.LOG:
/home/jboss/temp/a.html
/home/jboss/temp/temp/b.html

TOTAL_REPORTS=`cat REPORTS.LOG | wc -l`
for (( i=0; i<$TOTAL_REPORTS; i++ ))
do
        a=`sed -n "$((i+1))""p" "REPORTS.LOG"`
        attachments=( "${attachments[@]}" "`echo "-a ${a} "`")
done
cat XYZ.LOG | mutt `echo "${attachments[@]}"` -s "Test" -b a@b.com

Issue is :

Sometimes code is executed appropriately and attachments are seen in the email whereas sometimes email is received without attachments and attachmens' file path are seen as broken string in as :

From : jboss@172.19.10.55
To : -@172.19.10.55;/home/j@172.19.10.55;oss/t@172.19.10.55;mp/a.html@172.19.10.55;

[PLEASE SEE THE HIGHLITED PATH ABOVE]

1 Like

Thanks DGPickett.

I shall try this now.

---------- Post updated at 12:55 PM ---------- Previous update was at 11:09 AM ----------

Not sure what's going wrong. Above solution works independently when run as a stand-alone command , but when run from within the script, it fails and no attachments are seen in the email. What we get is as mentioned above.

Any solution please........

---------- Post updated at 03:45 PM ---------- Previous update was at 12:55 PM ----------

It works when we change the order of mutt switches, i.e. put attachments at last.

cat XYZ.LOG | mutt  -s "Test" -b a@b.com `echo "${attachments[@]}"`

Maybe someone is gobbling up the -- or something like that. In some situations, the shell quotes together the subshell output, so passing it through a variable or function call may be needed to break it up. You can put a "truss/strace/tusc -fae -o /tmp/mutt.$$.tr" prefix on mutt in the shell script and see in detail what the actual call is like. Putting the attachment list last is a nice workaround, though.

The workaround of putting attachments list at last does not work always. There is something that breaks the attachments and appends ip to broken substrings but not sure what :confused:

Again, strace/truss/tusc can tell you what is happening and what is being called. mutt should work if the command line and environment are preserved.

#!/bin/ksh
{
        # ------------------------ #
        # --- Sendmail Headers --- #
        # ------------------------ #
        echo "From: sender@domain.com"
        echo "To: recipient@domain.com"
        echo "MIME-Version: 1.0"
        echo "Subject: Test mail attachment"
        echo 'Content-Type: multipart/mixed; boundary="-q1w2e3r4t5"'
        echo "---q1w2e3r4t5"

        # ------------------------ #
        # ---- Sendmail Body ----- #
        # ------------------------ #
        echo "Content-Type: text/plain"
        echo "Content-Disposition: inline"
        echo '---q1w2e3r4t5'
        cat XYZ.LOG
        echo '---q1w2e3r4t5'

        # ------------------------ #
        # - Sendmail Attachments - #
        # ------------------------ #
        while read file
        do
                echo "Content-Type: text/plain; charset=US-ASCII; name=$file"
                echo "Content-Disposition: attachment; filename=$file"
                echo '---q1w2e3r4t5'
                cat $file
                echo '---q1w2e3r4t5'
        done < REPORTS.LOG
        echo '---q1w2e3r4t5--'
} > sendmail.txt

/usr/lib/sendmail -t < sendmail.txt

Here attachment files are being read from REPORTS.LOG which has got file names as :

/home/jboss/temp/a.html
/home/jboss/temp/temp/b.html

Here files are separated by new line character "\n".

Hence we can change IFS to "\n" instead of default " " before files names are appended around -a inside the for loop

IFS_backup=$IFS
IFS=$'\n'
for (( i=0; i<$TOTAL_REPORTS; i++ ))
do
        a=`sed -n "$((i+1))""p" "REPORTS.LOG"`
        attachments=( "${attachments[@]}" "`echo "-a ${a} "`")
done
IFS=$IFS_backup

---------- Post updated 02-06-13 at 12:21 PM ---------- Previous update was 02-05-13 at 06:08 PM ----------

Issue found.
We know default IFS for bash shell is " " [[SPACE].
Hence while above script tries to read the attachments, for some reason string is broken.
So we can update script to set temperory IFS to "\n" while the attachment files are being read in a for loop and then set original IFS state.

TEMP_IFS=$IFS
IFS=$'\n'
for (( i=0; i<$TOTAL_REPORTS; i++ ))
do
        a=`sed -n "$((i+1))""p" "REPORTS.LOG"`
        attachments=( "${attachments[@]}" "`echo "-a ${a} "`")
done
IFS=$TEMP_IFS

This is tested and works as expected.

If you set IFS just in a subshell, when then subshell is gone, so is the funny IFS.