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 в однострочник, чтобы он автоматически выполнял такой же поиск для других идентификаторов. Итак, с помощью одной команды я хотел бы сделать следующее:
Вы могли бы сделать что-то подобное.
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
Я не тестировал этот код. Возможно, вам потребуется изменить номера полей, особенно в разделе, который удаляет идентификатор при обнаружении записи журнала «Завершено». Его легко сделать однострочным.