Иногда очень нужно почистить очередь сообщений в Postfix. Вот как мне сейчас.
Посмотреть всю очередь сообщений можно командой:
mailq
Или:
postqueue -p
1B85EC416F 54202 Sat Mar 18 11:00:07 noreply@example.com (connect to mail.microsoft.com[157.58.197.10]:25: Connection timed out) aaaaasssss@yndex.ru 1F319D246F* 35734 Wed Mar 22 10:33:41 noreply@example.com (delivery temporarily suspended: connect to example-ru.mail.protection.outlook.com[104.47.13.36]:25: Connection timed out) clearing@example.ru 14922CD3EF! 35892 Tue Mar 21 08:01:45 noreply@example.com (delivery temporarily suspended: connect to example-ru.mail.protection.outlook.com[104.47.14.36]:25: Connection timed out) clearing@example.ru
В результатах вывода имеем:
- 1F319D246F — идентификатор сообщения письма в очереди
- если после идентификатора стоит знак "*" — письмо находится в активной очереди на доставку
- если после идентификатора стоит знак "!" — письмо находится в очереди ожидания, попыток доставки его производится не будет
- 54202 — размер письма
- 54202 Sat Mar 18 11:00:07 — дата и время принятия письма
- noreply@example.com — отправитель
- (delivery temporarily suspended: connect to example-ru.mail.protection.outlook.com[104.47.13.36]:25: Connection timed out) — может быть указана причина, по которой письмо не отправлено и находится в очереди на на доставку
- aaaaasssss@yndex.ru — получатель
Удалить письмо можно по идентификатору:
postsuper -d 1F319D246F
Таким образом, с помощью mailq можно найти требуемые письма по отправителю, получателю или по сообщению о не возможности доставки. А потом удалить их.
Удалить письмо по отправителю:
mailq | grep "noreply@example.com" | awk '{ print $1 }' | tr -d '*!' | postsuper -d -
или
mailq | tail -n +2 | grep -v '^ *(' | awk 'BEGIN { RS = "" } { if ($7 == "noreply@example.com" && $9 == "") print $1 } ' | tr -d '*!' | postsuper -d -
Удалить письмо по получателю:
mailq | tail -n +2 | grep -v '^ *(' | awk 'BEGIN { RS = "" } { if ($8 == "aaaaasssss@yndex.ru" && $9 == "") print $1 } ' | tr -d '*!' | postsuper -d -
Удалить письмо по получателю, отправителю или причине:
mailq | grep -v "Queue ID" | while read line; do if [ "1" != `echo $line | wc -m` ]; then echo -n " "$line; else echo""; fi ; done | grep "Connection timed out" | awk '{ print $1 }' | tr -d '*!' | postsuper -d -
Бонус
Удалить письмо на нескольких серверах через соль по получателю:
salt "postfix*" cmd.run "mailq | tail -n +2 | grep -v '^ *(' | awk 'BEGIN { RS = \"\" } { if (\$8 == \"receiver@example.com\" && \$9 == \"\") print \$1 } ' | tr -d '*\!' | postsuper -d -"