Simple Mail List Shell Script

Trying to send a note to your 60 person club or neighborhood group? Sounds easy but it's not, because most user email agents do not offer list processing and if they did, you would be putting everyone's email address in the header. One trick is to put the real recipient's address in blind copy (BCC:) field, but that kind of email just looks too whacked for me.

I usually find most any shell script by searching the Internet, but all I could find for this problem were people who wanted to sell their mail scripts. So here is a free one that uses BSD mail to mail to each list member. The reasons I wanted a script like this is that A) it only has your account as the return address. B) By using the Unix mail utility, the script does not put all that extra header information in the email which comes from today's verbose user mail agents. And C) there is a separate error email returned if a recipient has exceeded disk quota, no longer has an account, and so on.

No Mail Loops
The basic problem with a mail list of course is that you want to send each mail so that there is one "from" and one "to" address and the user can hit reply to return a comment. But be careful not to use a virtual or aliased email addresses in the "from" field since the average user will just hit reply and that would send their comments back to the whole list and create a mail loop.

Be Sure to Test it First
Copy and paste the shell script into an editor and save it as "fredmail" or whatever. Then "chmod 755 fredmail" to make it directly interpreted by the shell. It takes the mail list file name and letter file name as arguments and sends the mail from the current user account. If the files are not specified, or do not exist, it indicates the problem. Test it with a mail list file containing just your email address in the form:

Mr. Fred & Fredia Smaznabuck <freds@hotaol.com>

Caution: The above email address form works with BSD mail, but not older versions of nail. Nail is designed to support comma delimited email addresses on the command line, but a bug in older versions of nail mistakes each space delimited string as a separate email address. SuSE 9.0 replaced BSD mail by symbolically linking to nail. However, SuSE 9.3 uses a newer version of nail that does not have the bug. Also, nail will send embedded attachments where the old BSD mail program did not.

In the mail script shown below, but commented out, is the ability to fetch the first space delimited string and use it in the email salutation. For example, if the email address format is:

Fred Smaznabuck <freds@hotaol.com>
Then, the email will begin:
Dear Fred,

After you see everything is working, then delete the -b blind copy option so you don't have to keep deleting all that extra email from your inbox.

You will probably want to create a special user account for each mail list. This will keep all the back and forth email in one group and in one account that can be easily saved and restored.

Finally, please remember that in the time it takes a Human to make one mistake, a computer can make billions of mistakes. So before you send that email blast, be sure to double check your mail list and double check your message. Then check it again before hitting the Enter key.


#    Copyright 2004 Tobin Maginnis
#    This program is free software; you can redistribute it and/or modify it
#    under the terms of the GNU General Public License as published by the Free
#    Software Foundation; either version 2 of the License, or (at your option)
#    any later version.
#
#    This program is distributed in the hope that it will be useful, but
#    WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
#    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
#    for more details.
#
#    The full text of this software license is at: http://www.gnu.org/licenses/gpl.txt
#    or to receive a written copy  of the GNU General Public License, write to
#    the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
#    02111-1307  USA
#
#!/bin/bash
if [ ${#@} != 2 ]; then
  echo "Usage: $0 MailList Letter"
else
  if [[ -e "$1" && -e "$2" ]]; then
    echo "Sending $2 to mail list: $1 ..."
    while read name ; do
      echo "Mailing: $name"
      # If you do not use a courtesy title like Mr., Ms., Dr., etc., then you can uncomment
      # this to insert the first name (first space delimited string) into the salutation:
      # echo "Dear ${name/\ */}," > tempmail
      # cat $2 >> tempmail
      # Change $2 in the next line to tempmail
      mail -s "Your Subject Line Goes Here" -R "reply to addr" -b "blind copy to me to confirm" "$name" < $2
    done < $1
    # Delete the last copy of tempmail.  Previous copies were replaced with the redirection operator ">".
    # rm tempmail
    echo "Finished mail list: $1"
  else
    echo "Cannot find mail list file: $1 and/or letter file: $2"
  fi
fi

Here is another version written by Jeroen Leijen that inserts the subject from the command line instead from the source of the program.


#   Simple E-mail Merge (sem)
#   Copyright (C) 2007  Jeroen Leijen
#
#   This program is free software: you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation, either version 3 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   To read the GPL, see: http://www.gnu.org/copyleft/gpl.html
#   or see  for more details.
#
#!/bin/bash
#
# September 2007
# v.0.4
# by Jeroen Leijen
# http://jeroen.leijen.net
#
if [ ${#@} != 3 ]; then
  echo "Usage: $0 MailList Letter Subject(in quotes) "
else
  if [[ -e "$1" && -e "$2" ]]; then
    echo "Sending $2 with subject $3 to mail list: $1 ..."
    while read line ; do
      name=`echo $line| cut -d ',' -f 1`
      email=`echo $line| cut -d ',' -f 2`
      echo "Mailing: $name"
      echo "with e-mailaddress: $email"
      # You can change 'Dear' in the next line to whatever you need
      echo "Dear ${name}," > tempmail$$
      cat $2 >> tempmail$$
      mail -s "`echo $3`" `echo $email` < tempmail$$
      # if you like a bcc copy use this line
      # mail -s "`echo $3`" -b your_bcc_address@mail.comm `echo $email` < tempmail$$
    done < $1
    rm tempmail$$
    echo "Finished mail list: $1"
  else
    echo "Cannot find mail list file: $1 and/or letter file: $2"
  fi
fi

Want to know more about shell scripting? Try the Advanced Bash-Scripting Guide