Назад | Перейти на главную страницу

Какую команду я могу использовать для поиска в журналах sendmail ВСЕХ деталей сообщений, касающихся конкретного получателя.

CENTOS 5.x | Отправить почту

Иногда мне нужно поискать в журналах доставки sendmail, чтобы выяснить, что случилось с отсутствующим сообщением. Обычно это включает два (или более) шага:

ШАГ 1: Найдите в / var / log / maillog адрес электронной почты пользователя. Например grep -i "someuser@recipientdomain.com" / var / log / maillog

Обычно это возвращает что-то вроде этого:

  Jan 11 07:43:34 server-example sendmail[12732]: p937blksdh3: to=<someuser@recipientdomain.com>, delay=00:00:00, xdelay=00:00:00, mailer=esmtp, pri=102537, relay=mta.recipientdomain.com. [12.34.56.78], dsn=5.7.1, stat=Service unavailable

ШАГ 2: Затем я беру уникальное имя сообщения (в данном случае p937blksdh3) и ищу его. Например: grep -i p937blksdh3 / var / log / maillog

Я хочу объединить шаги 1 и 2 в однострочник, чтобы он автоматически выполнял такой же поиск для других идентификаторов. Итак, с помощью одной команды я хотел бы сделать следующее:

  1. Найдите в почтовом журнале sendmail определенную строку.
  2. Определите идентификатор сообщения (в приведенном выше примере это был p937blksdh3) для электронного письма. (Я догадываюсь awk '{print $}' будет использоваться?)
  3. Выполните поиск в том же журнале, но вместо этого ищите идентификатор сообщения (в основном grep -i p937blksdh3 / var / log / maillog в примере выше)
  4. Выведите результаты шага 3. Повторите это для других идентификаторов сообщений.

Вы могли бы сделать что-то подобное.

for i in `grep -i "someuser@recipientdomain.com" /var/log/maillog | awk '{print $5}'`; do grep -i $i /var/log/maillog; done

Это приведет к выделению строки для пользователя, которого вы ищете, а затем выберите 5-й элемент в строке (разделенный пробелами iirc). Затем для каждого идентификатора сообщения в этом списке будет выполняться поиск строк, содержащих идентификаторы сообщения.

Если вы хотите удалить: в конце идентификатора сообщения, вы можете сделать что-то вроде для i в grep -i "someuser@recipientdomain.com" /var/log/maillog | awk '{print $5}' | sed 's/\://; выполните grep -i $ i / var / log / maillog; сделано

Надеюсь, это поможет.

Это уточнение ответа Гарри.

Во-первых, awk может выполнять сопоставление с образцом, как grep, поэтому вы можете пропустить первый grep. Кроме того, вы можете получить дубликаты, поэтому мы можем удалить их с помощью sort -u:

for i in `awk '/someuser@recipientdomain.com/ {print $6}' /var/log/maillog | sort -u `; do grep -i $i /var/log/maillog; done

Эта версия использует два прохода через журнал почты:

awk '/someuser@recipientdomain.com/ {print $6}' /var/log/maillog | sort -u > /tmp/message-ids.list
grep -f /tmp/message-ids.list /var/log/maillog

В первой версии цикл for будет искать через mail.log столько идентификаторов сообщений, сколько найдено в журнале. Во второй версии grep будет использовать список идентификаторов сообщений в качестве фильтра и обрабатывать файл журнала только один раз, что будет более эффективно для большого файла журнала.

Это не прямой ответ на вашу конкретную проблему (Гарри ответил это уже), но просто подумайте о том, чтобы спланировать заранее, если вам часто нужна такая информация. Установить MIMEDefang а затем получить filter_recipient Регулярно регистрируйте всю необходимую информацию в удобном для вас формате.

Нет причин трубить grep в awk поскольку AWK может выполнять работу grep. Также нет причин использовать for цикл с grep может принимать шаблоны на свой стандартный ввод.

awk '/someuser@recipientdomain.com/ {print $6}' /var/log/maillog | sort -u  | grep -i -f - /var/log/maillog

Вы можете изменить это дальше, устраняя необходимость в sort -u (действительно, sort не нужно - вы могли бы использовать uniq)

awk '/someuser@recipientdomain.com/ {addr[$6]} END {for (a in addr) {print addr[a]}}' /var/log/maillog | grep -i -f - /var/log/maillog

Оба из них (и другие ответы) выполняют поиск за два или более прохода по файлу журнала. Было бы интересно посмотреть, будет ли следующая однопроходная техника более быстрой (и еще быстрее с использованием Perl или Python).

awk -v addr='someuser@recipientdomain.com' '$0 ~ addr {
         ids[$6]
     }
     {
         for (id in ids) {
             if ($0 ~ "^" ids[id] "$") {
                 print
             }
         }
     }
     $NF == "Completed" {
         delete ids[$1]
     }' /var/log/maillog

Я не тестировал этот код. Возможно, вам потребуется изменить номера полей, особенно в разделе, который удаляет идентификатор при обнаружении записи журнала «Завершено». Его легко сделать однострочным.