Как разделить одну почту с помощью procmail? - PullRequest
0 голосов
/ 04 июля 2019

У меня есть папка карантина, которую мне периодически приходится загружать и разбивать по почтовым ящикам получателей, а еще лучше разбивать каждое сообщение в текстовом файле. У меня есть ок. 10.000 писем в день, и я что-то кодирую с fetchmail и procmail. Проблема в том, что я не могу узнать, как разделить сообщение на сообщение в procmail; все они попадают в один и тот же почтовый ящик.

Я пытался передать каждое сообщение в сценарии с помощью рецепта, подобного:

    :0
    | script_processing_messages.sh

Который содержал

    read varname
    echo "$varname" > test_file

Чтобы узнать, смогу ли я получить одно сообщение в переменной $ varname, но нет, я получаю только одну строку сообщения каждый раз.

Прямо сейчас я использую

    fetchmail --keep

, где .fetchmailrc -

    poll mail.mymta.my protocol pop3 username "my@inbox.com" password "****" mda "procmail /root/.procmailrc"

и .procmailrc -

    VERBOSE=0
    DEFAULT=/root/inbox.quarantine

Я хотел бы получить файл для каждого сообщения, поэтому:

1.txt
2.txt
3.txt
[...]
10000.txt

У меня много получателей и много доменов, поэтому я не могу, скажем, написать 5000 правил, чтобы соответствовать каждому получателю. Было бы хорошо, если бы был какой-то

^To: $USER 

, которые перенаправляют на

/$USER.inbox

так что procmail сам позаботится о чтении и динамическом создании этих входящих сообщений

Я не очень разбираюсь в рецептах fetchmail и procmail, я очень стараюсь, но пока не пойду.

Ответы [ 2 ]

1 голос
/ 08 июля 2019

У вас, кажется, есть два или три разных вопроса; Правильный этикет для переполнения стека будет заключаться в том, чтобы спрашивать каждого по отдельности - это также помогает будущим посетителям, у которых есть только одна из ваших проблем.

Прежде всего, чтобы разделить mbox-файл Berkeley, содержащий несколько сообщений, и запустить Procmail для каждого отдельно, попробуйте

formail -s procmail -m <file.mbox

Возможно, вам потребуется прочитать о форматах почтовых ящиков, поддерживаемых Procmail . Почтовый ящик Berkeley - это отдельный файл, содержащий несколько сообщений, просто разделенных строкой, начинающейся с From (с пробелом после четырех буквенных символов). Этот разделитель должен быть уникальным, и поэтому сообщение, которое содержит эти пять символов в начале строки в теле, должно быть каким-либо образом экранировано (обычно путем написания > перед From).

Чтобы сохранить каждое сообщение в отдельном файле, выберите другой формат почтового ящика, чем в однофайловом формате Беркли. Конкретно, если местом назначения является каталог, Procmail создаст новый файл в этом каталоге. Как именно будет назван новый файл, зависит от содержимого каталога (если он содержит подкаталоги Maildir new, tmp и cur, новый файл создается в new в соответствии с соглашениями об именах Maildir) и о том, как именно указан каталог (косая черта и точка выбирают формат MH; в противном случае формат почтового каталога).

Сохранение в одном почтовом ящике для каждого получателя имеет ряд неприятных угловых случаев. Что если сообщение было отправлено нескольким местным получателям? Что делать, если адрес получателя не отображается в заголовках? и т. д. (Мини-FAQ по Procmail содержит раздел об этом в контексте виртуального хостинга домена, который, по сути, представляет собой вариант). Но если мы просто проигнорируем это, вы сможете выполнить что-то вроде

:0  # whitespace before ] is a literal tab
* ^TO_\/[^ @    ]+@(yourdomain\.example|example\.info)\>
{
    # Trim domain part from captured MATCH
    :0
    * MATCH ?? ^\/[^@]+
    ./$MATCH/
}

Это захватит в $MATCH первый адрес, который соответствует регулярному выражению, затем выполнит другое сопоставление регулярного выражения для захваченной строки, чтобы захватить только часть перед знаком @. Это, очевидно, требует, чтобы все адреса, которые вы хотите сопоставить, находились в наборе определенных доменов (здесь я использовал yourdomain.example и example.info; очевидно, заменили их фактическими именами доменов), и чтобы захват первого подходящего адреса был достаточным ( поэтому, если сообщение было To: alice@yourdomain.example и Cc: bob@example.info, то, какое из них ближе к началу сообщения, будет выбрано по этому рецепту, а другое будет проигнорировано).

Более подробно, специальный токен \/ заставляет Procmail скопировать текст, который соответствует регулярному выражению после этой точки, во внутреннюю переменную MATCH. Как показывает этот рецепт, вы можете выполнить сопоставление регулярных выражений для самой переменной, чтобы извлечь ее подстроку (или, другими словами, отбросить часть захваченного совпадения).

Действие ./$MATCH/ использует захваченную строку в MATCH в качестве имени папки для сохранения. Начальный ./ указывает текущий каталог (который равен значению переменной Procmail MAILDIR), а завершающий / выбирает формат почтового каталога.

Если ваши ожидаемые получатели не могут быть ограничены определенным набором доменов или иным образом сопоставлены одним регулярным выражением, я рекомендую задать новый вопрос с более ограниченной областью действия и достаточным количеством деталей, чтобы фактически определить, что вы хотите достигнуть.

0 голосов
/ 05 июля 2019

Я нашел решение части моей проблемы.

Похоже, в procmail нет способа позволить самому procmail распознавать получателя For без указания его в рецепте, поэтому я просто получил список и создал огромный файл рецептов.

Но потом я только что обнаружил, что для сохранения отдельных писем и во избежание огромных почтовых ящиков, заполненных большим количеством писем, можно просто написать рецепт вроде:

:0
* ^To: recipient@mail.it
/inbox/folder/recipient@mail.it/

Обратите внимание на / в конце: это заставит procmail создавать структуру папок, а не записывать все в один файл.

...