Thursday, September 18, 2014
Tuesday, September 16, 2014
The "mail" command accepts additional command line parameters, e.g.
$ mail root < /tmp/db_reorg.log $ echo "Coming home for dinner!" | mail firstname.lastname@example.org
Use subject for the e-mail title
Send copy of the mail to the specified address
Send blind carbon copy to specified address
Some common usage examples:
Send a log file to the system administrator: # mail -s "Reorganization completed" root < db_reorg.log Send mail to "mark" with copy to "john": $ echo "John's coming with us" | mail -c john -s "Join us watching Star Wars" mark
- Note that not all
/usr/ucb/mailx, or "
But how can we "attach" a file to a mail? We know that newer mail readers like Mozilla, Netscape Messenger or Microsoft Exchange have a way of displaying file attachments, e.g. images, ZIP files or audio files. How can we send some mail text (e.g. "See this picture of me surfing!") together with a binary file (e.g. "surfing.jpeg")?
The next chapter describes the traditional approach using "uuencode".
Sending binary files does not work well for the Internet. We could send a binary file "surfing.jpeg" using this command:
but chances are high that the image will be unusable the time it arrives at the recipient.
mail -s "picture of me surfing" email@example.com < surfing.jpeg
During mail delivery the mail is relayed from one mail delivery agent to the next, until it finally arrives at the recipient. Each delivery agent may transform the mail message, e.g. by stripping the 8th bit of each character, removing NUL bytes (ASCII code 0), converting the end-of-line character LF ("line-feed", ASCII code 12) to a local representation (e.g. CR LF), or removing trailing space or TAB characters from each line.
Since only some characters are sure to arrive unmodified, the traditional solution is to encode the mail from binary format to a text format that is safe to transmit. The program used for this is called "
uuencode" ("UNIX to UNIX encoding"), the program to decode the data is called "
The simplest way to send a file as a mail attachment is shown by the following example:
$ uuencode surfing.jpeg surfing.jpeg | mail firstname.lastname@example.org
That's all! If Sylvia uses a current mail reader like Mozilla, Netscape Messenger or Microsoft Exchange, she will see a mail containing just one file attachment: the file "surfing.jpeg". In the command above we had to specify the file name two times: the first name denotes the input file to be encoded, and the second name is the file name the recipient will see.
This way we can include normal text, too:
Note: The file name "surfing.jpeg" again appears twice on the
$ (cat mailtext; uuencode surfing.jpeg surfing.jpeg) | mail email@example.com
uuencodecommand line: the first time to specify the input file name, the second time for the remote extraction file name.
The first "
cat" will prepend the contents of the file "
mailtext" to the "uuencode"ed data of the image "
surfing.jpeg". Both commands are executed within a sub shell, to combine the output of both commands to one output stream redirected to the "mail" command.
This method of sending file attachments works fairly well, but still has some shortcomings:
- Many user agents cannot directly decode this kind of file attachments, e.g. "Eudora". Some mail agents explicitly require the decoding of the mail using the program "uudecode"
- The "uuencode" encoding is not standardized. Text encoded on one system may not be decoded correctly by the recipient's system
[the content of the mail message was saved to the file "mail.uue"] $ uudecode mail.uue The file "surfing.jpeg" was written to the current directory
The next method does not have this disadvantages. It works with most (newer) mail user agents and uses the "Multipurpose Internet Mail Extensions" (MIME).
The MIME Standard ("Multipurpose Internet Mail Extensions") defines an impressive list of new features for e-mail messages, e.g.
- arbitrary file attachments, e.g. images, audio files
- more than one file attachment per mail
- multi-part messages
Other features are non-ASCII character sets for message bodies and message headers.
But how can shell programmers use these features effectively?
At first there has to be a command-line driven program to send MIME mails. There are some MIME packages available free of charge, the most common being
- mutt written by Michael Elkins (http://www.mutt.org)
- MetaMail by Nathaniel S.Borenstein (ftp://ftp.research.telcordia.com/pub/nsb/)
- mpack by John G. Myers (ftp://ftp.andrew.cmu.edu:/pub/mpack/)
But check your local system before downloading one of these packages, many UNIX systems (e.g. Linux) come with one or more of them pre-installed.
mutt is an interactive, text-oriented e-mail client. Not very useful for usage in a script, one might think. But on closer view the program turns out to provide an easy way to send e-mails with file attachments. Have a look at the following example:
This command shows how to specify four important parts of an e-mail:
$ mutt -s "Birthday celebration" -a citymap.jpg firstname.lastname@example.org \ < invitation.txt
- The recipient ("email@example.com")
- The main body of the e-mail (read from standard input, here redirected from the file "invitation.txt")
- An attachment (with option
- A subject line (option
-a, which allows us to send an attachment (in this case a picture of a city map). We could have added more attachments by using multiple
mutt always reads a text from standard input that will become the main body of the e-mail, the text before the attachment. If the mail should consist of attachments only, we can either specify
/dev/nullas the file to read, e.g.
or use an empty line as the mail body:
$ mutt -a syslogs.tar.gz firstname.lastname@example.org < /dev/null
mutt does some work behind the scenes, e.g. it's looking at the file extensions of the attachments, and selects an appropriate MIME type for each. This works reasonably well (depending on the configuration of the system in general and mutt in particular), but if more control about MIME types and the sending of the e-mail is required, the next package may be more appropriate.
$ echo | mutt -a syslogs.tar.gz email@example.com
The remainder of this chapter will use programs of the MetaMail package for the examples. Don't worry if the command lines seem somewhat cryptic, at the end of this article we will present a script simplifying the sending of mail attachments.
MetaMail provides two programs to send mail:
metasend. We will use the second one for scripting, because it can be used non-interactively. The most interesting command line arguments of
metasendare listed in the following table [refer to metasend(1) for a complete list].
-b batch (non-interactive) mode -c cc CC address (for copy of the mail) -f filename Name of file to attach -m MIME-type MIME content type, e.g. "
text/plain" or "
-s subject Title (subject) of the mail message -t to Recipient's address -n Next file attachment (needed for multiple file attachments) -D description Description of the file content -o outputfile Name of an output file. If the -t option is given, the mail is sent directly to the addressee
This new knowledge enables us to send an audio file using "
$ metasend -b -t firstname.lastname@example.org -s "Hear our son!" \ -m audio/basic -f crying.au
This invocation of "metasend" sends a mail to "email@example.com" (option -t) with the subject "Hear our son!" (option -s), without prompting for further arguments (option -b). Without the "-b" argument, the command would have asked for addresses to send "carbon copies" to. The file to attach is called "crying.au", and the file type is "audio/basic".
The file type (or "MIME-type") "audio/basic" gives the recipient's mail reader a hint on the contents of the file attachment. Some contents may be displayed directly (e.g. "text/plain", "image/gif"), for others the mail reader may call external programs to present the contents (e.g. "application/postscript", "audio/wav"). The relation between MIME content type and external program to call often is established using a file called "mailcap" (see mailcap(4), if available on your system). Mozilla or Netscape's Communicator allows to specify "helper applications" that are invoked depending on the MIME type.
An annoying property of "metasend" is the need to specify the MIME type for each file. The script sendfile simplifies this. The following example sends two files, "
cover.gif" and "
$ sendfile firstname.lastname@example.org cover.gif contents.ps [Text to appear before the attachments, EOF to end] Hello John, you'll find a table of contents attached to this e-mail. ^D
The script is easier to use because it determines the MIME type of the specified files by examining their file name extension, e.g. ".gif" or ".ps".
The command used to determine the MIME type is getmimetype.