Next: , Up: sendmail   [Contents][Index]


A.1 How to compose a test email message

Here we discuss how to programmatically compose a minimal email message to be used in testing email scripts. Basically a message should look like this:

Sender: marco@localhost
From: marco@localhost
To: root@localhost
Subject: demo from sendmail-plain.sh
Message-ID: <15704-6692-23464@this.hostname>
Date: Tue, 28 Apr 2009 06:16:01 +0200

This is a text demo from the sendmail-plain.sh script.
--
Marco

We have to remember that the SMTP server receiving the message may rewrite the addresses, for example: replacing localhost with the fully qualified local host name (the output of the command hostname --fqdn); so, when reading the delivered message, we do not have to be surprised to find changed addresses.

We want to notice the following:

In the end, we can use the following chunk of code to compose an email message:

PROGNAME=${0##*/}
FROM_ADDRESS=marco@localhost
TO_ADDRESS=root@localhost

function print_message () {
    local LOCAL_HOSTNAME DATE MESSAGE_ID MESSAGE
    LOCAL_HOSTNAME=$(hostname --fqdn) || exit 2
    DATE=$(date --rfc-2822) || exit 2
    printf -v MESSAGE_ID '%d-%d-%d@%s' \
        $RANDOM $RANDOM $RANDOM "$LOCAL_HOSTNAME"
    MESSAGE="Sender: $FROM_ADDRESS
From: $FROM_ADDRESS
To: $TO_ADDRESS
Subject: demo from $PROGNAME
Message-ID: <$MESSAGE_ID>
Date: $DATE

This is a text demo from the $PROGNAME script.
--\x20
Marco
"
    printf "$MESSAGE"
}

notice that to put the required single white space character in the text/signature separator we use the escape sequence \x20 (where 20 is the hexadecimal value of the white space character in the ASCII encoding) and print the message with printf, which expands the escape sequences.

When sending the message to the SMTP server we have to:

So we can use an equivalent of the following chunk of code, assuming 3 is the file descriptor connected to the remote SMTP server:

print_message | while IFS= read line
do
    if test "${line:0:1}" = '.'
    then printf '.%s\r\n' "$line" >&3
    else printf  '%s\r\n' "$line" >&3
    fi
done

notice that read is executed in an environment in which IFS is set to the empty string, this is to prevent unwanted modification of the message text. read splits the string it reads into words according to the current value of IFS, and this may lead to mutation of the input string; word splitting happens when there is a single output variable, too. To prevent word splitting, we set IFS to the empty string.


Next: , Up: sendmail   [Contents][Index]

This document describes version 3.0.0-devel.0 of Marcos Bash Functions Library.