A utility for sending complex email messages from the command line

1420

Author: Ben Martin

When the need arises to send email from the command line, many folks first think of the mail(1) command. A better choice might be the email program, which gives you the ability to send email to an SMTP server over SSL, offers MIME support including ability to attach one or more files to your emails, uses an address book to store your recipients, and lets you digitally sign and encrypt your messages.

While there are tools to allow you to send complex email messages from Perl or PHP, being able to send email directly from the command line is handy for cron jobs and other applications where you just want to quickly send a message with an attachment.

Because the project is simply called email, I will refer to it as the “email program” in this article to avoid ambiguity. Because the project name “email” is so general I had a hard time searching for packages. I could not find any for Ubuntu or Fedora, but there is a 1-Click install for openSUSE 10.3. For this article I’ll build the program from source on a 64-bit Fedora 8 machine using the usual ./configure; make; sudo make install sequence.

If you do not explicitly change the prefix or sysconfdir when running ./configure, you will find the systemwide configuration file at /usr/local/etc/email/email.conf when you finish the install. If the file ~/.email.conf exists then email will use that; otherwise it will fall back to the system configuration file. You will want to change the MY_NAME and MY_EMAIL options in your personal configuration file. If you cannot send email through localhost, you’ll also have to set up the SMTP variables to point to your server and allow authentication. The default signature file includes a little blurb about being created by the email program, which you might like to disable.

$ cp /usr/local/etc/email/email.conf ~/.email.conf $ vi ~/.email.conf ... SMTP_SERVER = '127.0.0.1' SMTP_AUTH='PLAIN' SMTP_AUTH_USER='foo' SMTP_AUTH_PASS='bar' USE_TLS='true' ... MY_NAME = 'Sysadmin number one' MY_EMAIL = 'sadmin@example.com' ... #SIGNATURE_FILE = '&/email.sig' #SIGNATURE_DIVIDER = '---' ...

Once you have the software set up, you can send email messages from the command line using the email command. The first email below is sent in a very similar manner to the way the mail(1) program works. I specify the subject and recipient on the command line, then read the body of the message from the user before sending the message. Instead of the message being read in directly from the console as mail(1) does, the email program will run your nominated text editor to allow you to compose your message. In the second example below I send the current time as the message body with a subject line describing what happened at that time.

$ email --subject test1 ben@localhost email: WARNING: Deprecated variable: SIGNATURE_DIVIDER email: WARNING: Environment varaible EDITOR not set: Defaulting to "vi" hello there ZZ $ date | email --subject "Bad things happen at night" ben@localhost

The email program also lets you use an address book, which can be handy if you are using email to send out notifications and your email address changes, or you wish to send a message to a group instead of just yourself. The address book format allows for single or multiple recipient addresses. It is a good idea to always start out using addresses from the address book in scripts, using the specific task that the script is performing as the address in your address book. For example, a database backup script might send to the “database-archive” address from your address book. You can then easily change who will see such messages by changing your address book and not have to look at the scripts that send the email messages at all.

Recipients in the address book start with the tag single: or group:. Single email addresses are in the form name = email-address. Multiple email addresses are specified in a comma-separated list in a group email definition. The README file for email states that every recipient in a group address must be defined as a single address; that is, you cannot directly specify email addresses as recipients in a group definition. So, as shown below, the group address “us” references to single addresses “moi” and “anata” instead of using the email addresses like root@localhost directly.

$ vi ~/.email.conf ... ADDRESS_BOOK = '~/.email.address' .. $ cp /usr/local//etc/email/email.address.template ~/.email.address $ vi ~/.email.address ... single: moi = ben@localhost single: anata = root@localhost group: us = moi, anata ...

By default the address book names that you use show up in the email messages that are sent. As you can see in the below message, because I sent to the address “moi,” the To line in the resulting email contains “moi” <ben@localhost.localdomain>. If you want to keep the address book names and recipients from knowing who else is getting the messages, you can send the message to a single target address and use the --bcc option to blind carbon copy the message to a group. This will also keep the address book name that was used in the bcc target from being sent to the recipients.

$ date | email --subject "linux.com, eh?" moi $ vi /var/spool/mail/ben ... From yourlogin@example.com Tue May 27 12:33:57 2008 Return-Path: <yourlogin@example.com> Received: from v8tsrv (localhost.localdomain [127.0.0.1]) by localhost.localdomain (8.14.1/8.14.1) with ESMTP id m4R2Xv8w014763 for <ben@localhost>; Tue, 27 May 2008 12:33:57 +1000 Message-Id: <200805270233.m4R2Xv8w014763@localhost.localdomain> Subject: linux.com, eh? From: "Your Real Name" <yourlogin@example.com> To: "moi" <ben@localhost.localdomain> Date: Tue, 27 May 2008 12:33:57 +1000 Content-Type: text/plain X-Mailer: Cleancode.email v3.0.5 Tue May 27 12:33:57 EST 2008 ... $ date | email --subject "Singing and dancing monkies?" us From yourlogin@example.com Tue May 27 12:35:52 2008 Return-Path: <yourlogin@example.com> Received: from v8tsrv (localhost.localdomain [127.0.0.1]) by localhost.localdomain (8.14.1/8.14.1) with ESMTP id m4R2ZqEq014772; Tue, 27 May 2008 12:35:52 +1000 Message-Id: <200805270235.m4R2ZqEq014772@localhost.localdomain> Subject: Singing and dancing monkies? From: "Your Real Name" <yourlogin@example.com> To: <ben@localhost.localdomain>, "anata" <root@localhost.localdomain> Date: Tue, 27 May 2008 12:35:52 +1000 Content-Type: text/plain X-Mailer: Cleancode.email v3.0.5 Tue May 27 12:35:52 EST 2008 $ date | email --subject "You can't tell the group" --bcc us moi # vi /var/spool/mail/root ... From yourlogin@example.com Tue May 27 12:39:13 2008 Return-Path: <yourlogin@example.com> Received: from v8tsrv (localhost.localdomain [127.0.0.1]) by localhost.localdomain (8.14.1/8.14.1) with ESMTP id m4R2dDKY014832; Tue, 27 May 2008 12:39:13 +1000 Message-Id: <200805270239.m4R2dDKY014832@localhost.localdomain> Subject: You can't tell the group From: "Your Real Name" <yourlogin@example.com> To: "moi" <ben@localhost.localdomain> Date: Tue, 27 May 2008 12:39:13 +1000 Content-Type: text/plain X-Mailer: Cleancode.email v3.0.5 Tue May 27 12:39:13 EST 2008 ...

You can attach a file to a message by using the --attach command-line option and specifying the path of the file to attach. You can use the --attach option multiple times to include many files.

Use the --sign and --encrypt options to digitally sign and encrypt a message before sending. I found that the --sign option attempted to digitally sign the message using the private key of the first recipient rather than the private key of the message sender. For example, if sending from sadmin@localhost to ben@hawaii.example.com, the email program would try to use the private key of ben@hawaii to sign the message. This would normally fail because only the private key of sadmin@localhost is available on the machine. Of course if you always send to sadmin@localhost as the first address, then digital signing works as expected because the program looks for the correct key.

You can also override the SMTP server and authentication information, as well as the path of the configuration file, by using command-line options.

The email program is fairly quick to install and set up. The ability to send messages using an arbitrary SMTP server and the support that the email program has for connecting to an SMTP server using SSL let you send messages through whatever outgoing server you like. The support for attachments, encryption, and an address book makes sending email from the command line simple for automated scripts such as cron jobs. Having error reports from such scripts encrypted and signed also protects you against pranks and allows such reports to be sent through public email servers while remaining confidential.

Categories:

  • Mail & Messaging
  • Shell & CLI
  • Tools & Utilities