InfinityQuest - Programming Code Tutorials and Examples with Python, C++, Java, PHP, C#, JavaScript, Swift and more

Menu
  • Home
  • Sitemap

Python Programming Language Best Tutorials and Code Examples

Learn Python Right Now!
Home
Bash
Sending Email from Your Script in bash
Bash

Sending Email from Your Script in bash

InfinityCoder April 4, 2017

You’d like your script to be able to send email, optionally with attachments.

These solutions depend on a compatible mailer such as mail, mailx, or mailto, an
Message Transfer Agent (MTA) being installed and running, and proper configuration of your email environment.

Unfortunately, you can’t always count on all of that, so these solutions must be well tested in your intended environment.
The first way to send mail from your script is to write some code to generate and send a message, as follows:

1
2
3
# Simple
cat email_body | mail -s "Message subject" recipient1@example.com recipient2@example.
com

or:

1
2
3
# Attachment only
$ uuencode /path/to/attachment_file attachment_name | mail -s "Message Subject"
recipient1@example.com recipient2@example.com

or:

1
2
3
# Attachment and body
$ (cat email_body ; uuencode /path/to/attachment_file attachment_name) | mail -s
"Message Subject" recipient1@example.com recipient2@example.com

In practice, it’s not always that easy.

For one thing, while uuencode will probably be there, mail and friends may or may not, or their capabilities may vary.

In some cases mail and mailx are even the same program, hard- or soft-linked together.

In production, you will want to use some abstraction to allow for portability.

For example, mail works on Linux and the BSDs, but mailx is required for Solaris since its mail lacks support for -s. mailx works on some Linux distributions (e.g., Debian), but not others (e.g., Red Hat).

We’re choosing the mailer based on hostname here, but depending on your environment using uname -o might make more sense.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# cookbook filename: email_sample
 
# Define some mail settings. Use a case statement with uname or hostname
# to tweak settings as required for your environment.
case $HOSTNAME in
  *.company.com    )MAILER='mail' ;; # Linux and BSD
  host1.*          )MAILER='mailx' ;; # Solaris, BSD and some Linux
  host2.*          ) MAILER='mailto' ;; # Handy, if installed
esac
RECIPIENTS='recipient1@example.com recipient2@example.com'
SUBJECT="Data from $0"
 
[...]
# Create the body as a file or variable using echo, printf, or a here-document
# Create or modify $SUBJECT and/or $RECIPIENTS as needed
[...]
 
( echo $email_body ; uuencode $attachment $(basename $attachment) ) \
| $MAILER -s "$SUBJECT" "$RECIPIENTS"

We should also note that sending attachments in this way depends somewhat on the client you use to read the resulting message, too.

Modern clients like Thunderbird (and Outlook) will detect a uuencoded message and present it as an attachment.
Other clients may not.

You can always save the message and uudecode it (uudecode is smart enough to skip the message part and just handle the attachment part), but that’s a pain.
The second way to send mail from your scripts is to outsource the task to cron.
While the exact feature set of cron varies from system to system, one thing in common is that any output from a cron job is mailed to the job’s owner or the user defined using the MAILTO variable.

So you can take advantage of that fact to get emailing for free, assuming that your email infrastructure works.
The proper way to design a script intended to run from cron (and many would argue any script or Unix tool at all) is to make it silent unless it encounters a warning or error.

If necessary, use a -v argument to optionally allow a more verbose mode, but don’t run it that way from cron, at least after you’ve finished testing.

The reason for this is as noted: cron emails you all the output.

If you get an email message from cron every time your script runs, you’ll soon start ignoring them.

But if your script is silent except when there’s a problem, you’ll only get a notification when there is a problem, which is ideal.

Note that mailto is intended to be a multimedia and MIME-aware update to mail, and thus you could avoid using uuencode for sending attachments, but it’s not as widely available as mail or mailx.

If all else fails, elm or mutt may be used in place of mail, mailx, or mailto, thought they are even less likely to be installed by default than mail*.

Also, some versions of these programs support a -r option to supply a return address in case you want to supply one. mutt also has a -a option that makes sending attachments a breeze.

1
cat "$message_body" | mutt -s "$subject" -a "$attachment_file" "$recipients"

mpack is another tool worth looking into, but it is very unlikely to be installed by default.

Check your system’s software repository or download the source from ftp:// ftp.andrew.cmu.edu/pub/mpack/.

From the manpage:

1
2
3
The mpack program encodes the named file in one or more MIME messages. The
resulting messages are mailed to one or more recipients, written to a named file or set
of files, or posted to a set of newsgroups.

Another way to handle the various names and locations of mail clients is shown in Chapter 8 of Classic Shell Scripting by Nelson H.F.

Beebe and Arnold Robbins (O’Reilly):

1
2
3
4
5
6
7
# cookbook filename: email_sample_css
# From Chapter 8 of Classic Shell Scripting
for MAIL in /bin/mailx /usr/bin/mailx /usr/sbin/mailx /usr/ucb/mailx /bin/mail /usr/
bin/mail; do
    [ -x $MAIL ] && break
done
[ -x $MAIL ] || { echo 'Cannot find a mailer!' >&2; exit 1; }

uuencode is an old method for translating binary data into ASCII text for transmission over links that could not support binary, which is to say most of the Internet before it became the Internet and the Web.

We have it on good authority that at least some such links still remain, but even if you never encounter one it’s still useful to be able to convert an attachment into an otherwise ASCII medium in such a way that modern mail clients will recognize it.

See also uudecode and mimencode.

Note that uuencoded files are about one-third larger than their binary equivalent, so you probably
want to compress the file before uuencoding it.
The problem with email, aside from the differing front-end Mail User Agent (MUA) programs like mail and mailx, is that there are a lot of moving parts that must all work together.

This is exacerbated by the spam problem because mail administrators have had to so severely lock down mail servers that it can easily affect your scripts.

All we can say here is to fully test your solution, and talk to your system and mail administrators if necessary.
One other problem you might see is that some workstation-oriented Linux distributions, such as Ubuntu, don’t install or run an MTA by default since they assume you will be using a full-featured GUI client such as Evolution or Thunderbird.

If that’s the case, command-line MUAs and email from cron won’t work either.

Consult your distribution’s support groups for help with this as needed.

Share
Tweet
Email
Prev Article
Next Article

Related Articles

Creating a Simple RPN Calculator in bash
You may be able to convert binary to decimal, octal, …

Creating a Simple RPN Calculator in bash

Running Several Commands in Sequence in bash
You need to run several commands, but some take a …

Running Several Commands in Sequence in bash

About The Author

InfinityCoder
InfinityCoder

Leave a Reply

Cancel reply

Recent Tutorials InfinityQuest

  • Adding New Features to bash Using Loadable Built-ins in bash
    Adding New Features to bash Using Loadable …
    June 27, 2017 0
  • Getting to the Bottom of Things in bash
    Getting to the Bottom of Things in …
    June 27, 2017 0

Recent Comments

  • fer on Turning a Dictionary into XML in Python
  • mahesh on Turning a Dictionary into XML in Python

Categories

  • Bash
  • PHP
  • Python
  • Uncategorized

InfinityQuest - Programming Code Tutorials and Examples with Python, C++, Java, PHP, C#, JavaScript, Swift and more

About Us

Start learning your desired programming language with InfinityQuest.com.

On our website you can access any tutorial that you want with video and code examples.

We are very happy and honored that InfinityQuest.com has been listed as a recommended learning website for students.

Popular Tags

binary data python CIDR convert string into datetime python create xml from dict python dictionary into xml python how to create xml with dict in Python how to write binary data in Python IP Address read binary data python tutorial string as date object python string to datetime python

Archives

  • June 2017
  • April 2017
  • February 2017
  • January 2017
  • December 2016
  • November 2016
Copyright © 2021 InfinityQuest - Programming Code Tutorials and Examples with Python, C++, Java, PHP, C#, JavaScript, Swift and more
Programming Tutorials | Sitemap