Sorting and Forwarding Mail with Procmail
Procmail is a program to sort, filter, forward, and otherwise organize
incoming e-mail messages. This qref explains how to use procmail for some
common sorting purposes. The examples given here will definitely work if
you use pine to read e-mail on turing. They have not been
tested under other circumstances but will most likely work anyway.
- To make procmail filter your mail you need to create a .procmailrc
file in your home directory. If you already have a .forward
file you should remove (or rename) it. (See the notes section for more
information.)
- The .procmailrc file contains rules (commonly called "recipes") for
handling incoming
messages. A procmail
recipe consists of a condition and an action, much like your normal
everyday
if statement. Each recipe is executed in turn;
the first one that matches will be the one that is executed
(but there is a way to have
mail keep falling through recipes, keep reading).
- At the top of the .procmailrc you should set some environment
variables. These control the way procmail behaves.
Here is an example,
the meaning of each variable is explained below.
MAILDIR=$HOME/Mail
DEFAULT=$HOME/mailbox
LOGFILE=$MAILDIR/log
MAILDIR - "Current directory while procmail is
executing
(that means that all paths are relative to
$MAILDIR)." (rogue(5)) It is important to make sure that
whatever directory you specify actually exists.
DEFAULT - If an e-mail message does not match any
rules
it will be delivered to this mailbox.
LOGFILE - This specifies a log file that will
will store the time and subject of all messages received and which
folder they were delivered to. It also logs some error messages. The
file, named log in this example, can be read using less
or your favorite text editor. It is recommended that you use a log
file.
HOME - A variable that is already defined by the shell.
It stores the location of your home directory,
usually /home/userName.
$ - The value of a variable is gotten by putting a $
sign in front it.
Read procmailrc(5) for more information on
environment variables.
- Anything after a '#' (pound sign) is a comment. Condition lines start with
an '*' (asterisk). You cannot have
a comment on the same line as a condition.
This will make more sense after we look at an example.
- The following is a procmail recipe.
# Deliver mail addressed to thee linux-l mailing list
# to the linux-l folder (in the MAILDIR directory).
:0:
* ^TO_linux-l@hmc\.edu.*$
linux-l
- Anatomy of a procmail recipe:
:0 [flags] [: [locallockfile]]
All procmail
recipes
start
with colon
zero. Square brackets indicate optional things.
If you want a lock file you should include the second colon. A
lock file prevents messages from being overwritten if one arrives while
a previous one is being processes. For most simple recipes the default
lock file (no name given) is sufficient. If you want to name your own
lock file you can do so after the second colon. There are several
flags you can include after the zero but before the second colon to
make procmail behave in various ways.
A c after the zero will make a copy of the e-mail to keep falling
through the filters.
One can think of it as the "copy" flag,
so it will get delivered to more than one mailbox. Perhaps I can have
my .procmailrc setup so that important mail goes to my inbox and a
filtered folder for eternal storage, and other mail goes straight to
the filtered folder. Then when reading my inbox I need only delete the
message, knowing that I have an archived copy already. Another REALLY
USEFUL use of the 'c' flag is to have a backup folder that EVERYTHING
gets copied to - it'll save your butt while setting up procmail such
that a mistyped recipe doesn't make you lose your mail (see an
example of this below).
Read procmailrc(5) for more information on other available
flags.
* ^TO_linux-l@hmc\.edu.*$ This line is a
condition. Condition lines start with an asterisk. The only
other thing on the line is a regular expression. condition
lines. If the header of the incoming mail message matches the
given regular expression then the action for that recipe is
taken. This regular expression says that the message must be
addressed to the address linux-l@hmc.edu. ^TO_ will be
expanded by procmail as follows (as described in
procmailrc(5) ): If the regular expression contains
`^TO_' it will be substituted by
`(^((Original-)?(Resent-)?(To|Cc|Bcc)|
(X-Envelope|Apparently(-Resent)?)-To):(.*[^-a-zA-Z0-9_.])?)',
which should catch all destination specifications containing a
specific address. The '.' (period aka dot) character will match any
character. The '*' (asterisk aka star) matches zero or more of the
proceeding character. So the regular expression '.*' (dot star)
matches zero or more
of any character. In order to turn off a special character,
you can proceed it with a '\' (slash) character.
Regular expressions are
the heart of procmail.
To learn about all the possible regular expressions read
procmailrc(5). Each recipe may have zero or more
condition lines. If there are zero condition lines, the
corresponding action will be taken for every message. Multiple
condition lines are anded together.
linux-l
The line after the condition(s) tells procmail where to deliver the
message. In this case it will be delivered to the linux-l
folder. Read the note on pine folders before creating any for
yourself. If you place an ! exclamation mark at the beginning of the
action line procmail will forward the message to the address(es) that
follow.
- The following are working procmail recipes. Feel free to use them.
# If this is the first recipe in your .procmailrc file it will back up all your
# before sorting it mail.
# A copy of the message will be put into the backup folder.
# Notice the c flag. That means a copy of the mail message will fall through
# to the rest of your recipes.
# Notice that there is no condition, therefor all messages are handled.
:0 c:
backup
# Deliver any message generated by the request system into the request folder.
# This regular expression matches if the subject line contains one of
# NewReq, CloseReq, UpdtReq, AsgnReq, ReopnReq, or ChgPrty.
:0:
* ^Subject:.*(NewReq|CloseReq|UpdtReq|AsgnReq|ReopnReq|ChgPrty).*$
request
# Unlocked term messages delivered to the unlockedterm folder.
:0:
* ^Subject:.*(Unlocked Terminal - Security Risk)$
unlockedterm
# Any message sent to consult or consultant @turing.cs.hmc.edu or @cs.hmc.edu
:0:
* ^.*consult(ant)?@(turing.)?cs\.hmc\.edu.*$
consult
# Submissions. These are sent by the submit script.
# Matches mail whose subject line contains the word "submission"
:0:
* ^(Subject):.*submission.*$
submissions
# Forward any e-mail to or from the cs-125-l list to the address
# anotherAccount@hmc.edu
:0:
* (^TO_|^From:.*)cs-125-l@hmc\.edu
! anotherAccount@hmc.edu
# You can simulate a .forward file with the following recipe:
# Notice there is no condition for this recipe. All messages match an empty
# condition, therefor all messages will be forwarded to the given address.
# When using a rule that forwards e-mail, be careful not to cause mail loops
# by forwarding from one account to another and back again.
:0
! anotherAccount@hmc.edu
# If you get duplicate copies of the same e-mail message
# procmail at all, you might be interested in the following procmailrc
# recipe, which will ensure that you see only one copy of any message no
# matter how many are delivered:
:0 Wh: msgid.lock
| /usr/local/bin/formail -D 8192 msgid.cache
# This recipe uses the | in the action line to feed the header of the
# e-mail (only the header because the 'h' flag is used) to another
# program, in this case formail.
# The W flag means:
# Wait for the filter or program to finish and check its
# exitcode (normally ignored); if the filter is unsuccessful,
# then the text will not have been filtered.
# And suppress any `Program failure' message.
# If you wish, you can replace
# "msgid.cache" with the pathname of a file somewhere else in your home
# directory so that it is hidden from your daily activities.
- Tips:
Use a recipe with no condition as the first recipe in your
.procmailrc file to have a rule that affects every message. Be sure
to use the c flag or no other recipe will ever be executed.
Use a recipe with no condition as the last recipe in your
.procmailrc file as a default rule. Any message that does not get
caught by a preceding rule will get caught by it.
Notes:
- .forward files: If you are currently using a .forward file to
forward e-mail from turing, and you want to use procmail, you
should remove your .forward file. The .forward file gets
executed before
the .procmailrc file and prevents procmail from ever seeing an
incoming message. The example section of this qref explains how to make
procmail forward mail.
- Procmail does not support the expansion of '~' tilde. If you want to refer
to your home directory use $HOME instead.
- Pine folders: Lets say you all your linux-l mail delivered to the linux-l
folder. Do NOT create a directory called linux-l. I did that at first,
its not a good thing. What you need to do is create a new folder within
pine. To do this, open pine. Choose the
L option to view the folder
list. Then type a to add a folder. Pine will prompt
you for the name of the new folder.
- For more information:
procmailrc(5) - Contains all the available environment
variables, recipe flags, and extended regular
expression. Very useful.
procmailex(5) - Examples of recipes for a variety of
situations. Very useful.
procmail(1) - About the procmail program itself. Very tedious
and not so useful for learning procmail.
procmailsc(5) - Procmail weighted scoring technique. I don't
know what that means.
lockfile(1) - More on lock files. Unnecessary for most
people.
Regular expression are vital to procmail so you should
become familiar with them. Procmail uses egrep regular
expressions. The available special characters and phrases
are listed in procmailrc(5) For more
information about regular
expressions, check out regexp(5) or the O'Reilly book
"Programming Perl".
Other tutorials on procmail can be found on the world wide web.
Simply
search google for them.
Last Modified Tuesday, 14-Oct-2003 15:26:04 PDT
|