'Procmail Replace / Add Subject to an Empty Subject Field

I have a recipe that cannot seem to match the address.

I tried these:

* ^From.*address9\@gmail\.com

* ^From.*[email protected]

* ^From.*address\[0-9\]\@gmail\.com

* ^From.*address\d\@gmail\.com

* ^From.*address\[email protected]

but none of the above-mentioned works... I am totally lost. It looks like regular expressions have its own logic and patterns in procmail.

Here is my full recipe. The address to match has this 9 at the end and it's gmail.com When I put any other email address into this * ^From.* field it works OK, but this one doesn't... Here is my full recipe. The conditions to match are: to add a tag [New Report] when it comes from [email protected] and the subject field is empty. I would really be thankful if somebody could advise please, as I am about to go nuts trying to understand where is the mistake here.

:0 fhw
* ^From.*address9\@gmail\.com 
* ^Subject:\/.+
| /usr/bin/formail -i "Subject: [New Report]$MATCH"

Would also be grateful for any pointers how to trouble shoot it. Many thanks in advance!

The header looks like this:

From: Name Lastname <[email protected]>
Date: Wed, 12 Jun 2019 20:37:17 +1200
Message-ID<CADxD3vdy5cW55mogOK5+543ngU7iFKjJcpDV3Q4YL772F=LdQ@mail.gmail.com>
Subject: 


Solution 1:[1]

Regular expressions are pretty simple actually. Nearly every character simply matches itself. So if you have (beginning of line) F r o m : followed by anything followed by a d d r e s s 9 ... it should match.

Procmail doesn't support various Perl extensions like \d or \t, and of course there is no need to backslash characters which don't have a special meaning in regex like @. If you want to match a single digit that's [0-9] without any backslashes (those would change [ and ] back into literal matches).

^Subject:\/.+ checks that there is at least one character in the Subject: header and collects it all into $MATCH. This does not check that the subject is empty. Perhaps you want something like

# \t is not supported, replace with a literal tab character
* ^Subject:[ \t]+$

where the \t should be replaced with a literal tab. Every message should contain a Subject: header so it will always be there, but if its value consists entirely of whitespace, that is considered an empty subject. And of course, if the header is empty, there is no need to capture its contents.

Reviewing your attempts, here are some comments on each.

  • ^From.*address9\@gmail\.com

    As suggested above, the backslash before @ is superfluous, but harmless. This should match any header line which starts with From and which contains [email protected] somewhere later on the same line.

  • ^From.*[email protected]

    The unescaped dot matches any character, so this would also match [email protected] for example.

  • ^From.*address\[0-9\]\@gmail\.com

    The square brackets are escaped, and thus matched literally. This will match any line which starts with From and which contains the literal text address[0-9]@gmail.com somewhere later on the line, which is unlikely in practice.

  • ^From.*address\d\@gmail\.com

    Procmail does not support the Perl escape \d for a digit, so this would match literally [email protected] on a header line starting with From.

  • ^From.*address\[email protected]

    As above, with the unescaped dot again matching any character in addition to a literal dot.

Having said that, your second condition would match if there is at least a single space after the colon in Subject: so again, it really should match in your test case unless there really is absolutely nothing in the Subject: header.

So anyway, if that was your problem, the From: recipe might actually have been matching, but the Subject condition was not matching. With Procmail VERBOSE logging you would see each regex with "matched" or "no match" in the log file.

:0 fhw
* ^From.*address9@gmail\.com\>
* ^Subject:[    ]*$
| /usr/bin/formail -i "Subject: [New Report]"

(The added word boundary \> prevents com from matching if it is part of a longer word.)

Or perhaps you want to do this with any Subject: header? (This time I'm using a proper literal tab - check that you copy/paste this properly, though! There should be a space and a tab between [ and ].)

:0 fhw
* ^From.*address9@gmail\.com\>
* ^Subject:[    ]*\/.*$
| /usr/bin/formail -i "Subject: [New Report] $MATCH"

For troubleshooting, perhaps have a look at http://www.iki.fi/era/mail/procmail-debug.html

The Stack Overflow Minimal Reproducible Example guidance is also useful. Briefly, try to reduce the problem to the simplest input message and the simplest recipe which doesn't behave like you expect, then once you can't reduce it any further, take a good sharp look at what you are left with. Common causes of confusion include

  • malformed input messages
    • Empty lines in what's supposed to be the headers?
    • Headers wrapped over multiple physical lines?
    • Pesky control characters where there aren't supposed to be, either in the message or in your Procmail script (don't use Windows editors^W)
  • unwarranted assumptions
    • Regex doesn't work like you thought?
    • Procmail's regex dialect is different than e.g. Perl's? Online regex testers typically assume a Perl (or occasionally Javascript) regex feature set
    • Procmail matches against only the headers by default; some beginners miss this and are surprised when it doesn't find a string which is plainly there, only in the body
    • MIME content-transfer-encoding obscures the content you thought you knew was there?
    • Your regex really has to match a literal piece of text in the message; Procmail does no normalization e.g. to extract just the sender address in a convenient form for matching.

... Oh, and everyone's favorite: Make sure you set SHELL=/bin/sh right at the top of your recipe file. This has been the source of many otherwise completely mysterious failures over the years.

Here is a quick demo to demonstrate that your test case works for me:

tripleee@debian$ cat >test.msg
From: Name Lastname <[email protected]>
Date: Wed, 12 Jun 2019 20:37:17 +1200
Message-ID<CADxD3vdy5cW55mogOK5+543ngU7iFKjJcpDV3Q4YL772F=LdQ@mail.gmail.com>
Subject: 

No fooling
^D

tripleee@debian$ cat >test.rc
SHELL=/bin/sh
DEFAULT=/dev/null
VERBOSE=yes

:0 fhw
* ^From.*address9\@gmail\.com 
* ^Subject:\/.+
| /usr/bin/formail -i "Subject: [New Report]$MATCH"
^D

tripleee@debian$ procmail -m test.rc <test.msg 
procmail: [3717] Wed Jun 12 13:38:55 2019
procmail: Match on "^From.*address9\@gmail\.com"
procmail: Assigning "MATCH="
procmail: Matched " "
procmail: Match on "^Subject:\/.+"
procmail: Executing " /usr/bin/formail -i "Subject: [New Report]$MATCH""
procmail: Assigning "LASTFOLDER=/dev/null"
procmail: Opening "/dev/null"
From [email protected]  Wed Jun 12 13:38:55 2019
 Subject: [New Report] 
  Folder: /dev/null                             253

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1