NAME

proctip1 - use variables for cleaner recipes

SYNOPSIS

Procmail allows you to define custom variables; judicious use of custom variables can make your recipes easier to read and maintain. Defining a variable is as simple as this:

    SOMEVAR = "some value"

(Whitespace surrounding the "=" sign is optional). Common variable values are mailbox locations, newlines, whitespace, supremum value, double quotes, and program paths.

EXAMPLE

Consider this ugly recipe:

    :0
    * H ?? $ ^Content-Type:[    ]*multipart/alternative;[       ]*boundary=\"?\/[^\"]+
    {
        LOG="Found MIME-encoded message
    "

        :0:
        /var/tmp/empty
    }

Think about a whole file full of recipes just like this one! Now consider this more elegant version using variables:

    ## these variables are defined once at the top of the file or as
    ## part of an INCLUDERC file

    ## define common variables
    nl="
    "
    ws="[       ]"

    ## define abbreviations
    ct="Content-Type:${ws}*"
    ma="multipart/alternative"

    ## mailbox
    EMPTY="/var/tmp/empty"

    ## and here's our recipe
    :0
    * H ?? $ ^${ct}${ma};${ws}*boundary=\"?\/[^\"]+
    {
        LOG="Found MIME-encoded message${nl}"

        :0:
        $EMPTY
    }

Of course, defining all those variables is a lot of work for just a single recipe, but most recipes use the same parts over and over (the whitespace variable is probably one of the most common), which means that the more recipes you have, the more opportunities to consolidate these common parts into variables.

DISCUSSION

Notice the following things with our example above:

  1. The ct variable definition contains another variable (ws). We can combine variables this way like building blocks. If we define our variables using useful and easy-to-read names (admittedly, ct is too brief for general use, but appropriate in a small context like this single recipe), we can get succinct and more compact recipes.
  2. We wrap our variables with curly braces. This isn't necessary except when there is text immediately after a variable that could change the variable name. For example, in our above recipe, if we didn't have an asterisk after ${ws} so that the condition like appeared thus:
  3.     * H ?? $ ^${ct}${ma};${ws}boundary=\"?\/[^\"]+

    the curly braces are vital; without them we have this:

        * H ?? $ ^$ct$ma;$wsboundary=\"?\/[^\"]+

    The $ct and $ma variables are fine. The $ws variable has suddenly become $wsboundary, which is an empty variable (variables not defined are empty when procmail comes along to interpolate them). This is clearly not what we want, so we put curly braces around the ${ws} to separate it from 'boundary'.

  4. We use a variable to hold a newline. Procmail log lines don't automatically insert a newline, so we have to do it ourselves. The common way to get a custom line into the procmail log is by assigning to the LOG variable:
  5.     LOG="A simple log entry
        "

    Notice how the last double quote is on the next line? That's how we get a newline into our log entry. Yuck.

    Let's put the newline in a variable instead, so our log entries look clean:

        n="
        "
    
        LOG="A simple log entry$n"

    Much better! If you only have one LOG assignment, you're probably wasting your time by assigning a newline to a variable; but if you have more than one LOG entry, do yourself a favor (and anyone else who has to read your file in the future) and make your file more readable by using a variable instead.

    You'll often see NL, nl, or just n as we used above for the newline variable. It doesn't matter much as long as you're consistent.

  6. We can use a variable as our mailbox to deliver the message to. This makes it efficient if you have multiple recipes that deliver to the same location; if we need to change the location of the mailbox, we just change one variable at the top of the file instead of each recipe.

SUMMARY

Using variables (with short and descriptive names) makes procmail recipes more concise and easier to read.

SEE ALSO

procmail(1), procmailrc(5), procmailex(5)

AUTHOR

Scott Wiersdorf <scott@perlcode.org>

COPYRIGHT

Copyright (c) 2003 Scott Wiersdorf. All rights reserved.

REVISION

$Id: proctip1.pod,v 1.2 2003/10/03 17:49:16 deep Exp $