Pretty Emails from Shell Scripts

One of the key usage of shell scripts is to monitor systems and jobs and send out notification alerts to email addresses. With the advent of smartphones and always-connected devices, these emails are not limited to 140-characters of plain text and can provide a rich layout and format to make it easier to understand the issue at hand and provide useful recovery information for support personnel.

You can combine uuencode and sendmail to send formatted html notification emails with attachments. Use some shell scripting glue and you can put everything in a simple script as shown below.

Synopsis

notify_html <email> <subject> ["<attach1> [name1]" ... "<attachN> [nameN]"] < body.txt

Example,

gen_error_html | notify_html notify@example.org "Issue with job one" \
       "one.3212345.log one.log"

Script


typeset -r UTILS_UUENCODE=uuencode
typeset -r UTILS_SENDMAIL=sendmail

## Takes a list of file names and encodes them properly to be attached to an email
function process_attachments
{

    ## loop over all the remaining parameters and create uuencode commands to encode attachments
    for arg in "$@"
    do
        ## The remote name for the attachment is optional, so append the same name if it is missing
        if [[ $arg != *\ * ]]; then
            $UTILS_UUENCODE $arg $arg
        else
            $UTILS_UUENCODE $arg
        fi
    done
}

function notify_html 
{
    typeset -r SYSTEM=$(uname -s)
 
    typeset email="$1"
    typeset subject="$2"
    shift 2
    
    (
        ## pass-through email body content
        cat
        ## Add a footer
        echo "\n\rMessage generated from $system at $(date)"
        ## Add any attachments
        process_attachments "$@"
    ) | sendmail_html "$email" "$system: $subject"

    return $?
}

function sendmail_html
{
    typeset email="$1"
    typeset subject="$2"

    (
        echo "Subject: $subject"
        echo "MIME-Version: 1.0"
        echo "Content-Type: text/html"
        echo "Content-Disposition: inline"
        ## pass-through email body content, including attachments
        cat
    ) | $UTILS_SENDMAIL $email
}

notify_html "$@"