CENTOS 5.x | Sendmail
有时我需要搜索 sendmail 投递日志来查找丢失邮件的原因。这通常涉及两个(或更多)步骤:
步骤 1:在 /var/log/maillog 中搜索用户的电子邮件地址。例如grep -i “[电子邮件保护]“ /var/log/maillog”
通常会返回如下内容:
Jan 11 07:43:34 server-example sendmail[12732]: p937blksdh3: to=<[email protected]>, 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 合并为一行,并让其自动对其他 ID 执行相同的搜索。因此,在单个命令中,我想执行以下操作:
- 在 sendmail 邮件日志中搜索特定字符串。
- 识别电子邮件的消息 ID(在上面的示例中,这是 p937blksdh3)。(我猜awk'{打印$}'会被使用吗?
- 搜索相同的日志,但搜索消息 ID(基本上grep -i p937blksdh3 /var/log/maillog在上面的例子中)
- 输出步骤 3 的结果。对其他消息 ID 重复此操作。
答案1
你可以做类似的事情。
for i in `grep -i "[email protected]" /var/log/maillog | awk '{print $5}'`; do grep -i $i /var/log/maillog; done
这将 grep 出您要查找的用户的行,然后选择行上的第 5 项(以空格分隔,如果我没记错的话)。然后,对于该列表中的每个消息 ID,将 grep 出包含消息 ID 的行。
如果要从消息 ID 末尾删除 :,可以执行以下操作: for i in ; do grep -i $i /var/log/maillog; donegrep -i "[email protected]" /var/log/maillog | awk '{print $5}' | sed 's/\://
希望有所帮助。
答案2
答案3
这是对 Harry 的回答的改进。
首先,awk 可以像 grep 一样进行模式匹配,因此您可以跳过第一个 grep。此外,您可能会得到重复项,因此我们可以使用 sort -u 删除它们:
for i in `awk '/[email protected]/ {print $6}' /var/log/maillog | sort -u `; do grep -i $i /var/log/maillog; done
此版本使用两次通过邮件日志:
awk '/[email protected]/ {print $6}' /var/log/maillog | sort -u > /tmp/message-ids.list
grep -f /tmp/message-ids.list /var/log/maillog
在第一个版本中,for 循环将通过 mail.log 查找日志中找到的尽可能多的消息 ID。在第二个版本中,grep 将使用消息 ID 列表作为过滤器,并且只处理日志文件一次,这对于大型日志文件来说将更有效率。
答案4
由于 AWK 可以完成 grep 的工作,因此无需管道输入grep
。由于 AWK可以在其标准输入中接受模式,因此awk
也无需使用循环for
。grep
awk '/[email protected]/ {print $6}' /var/log/maillog | sort -u | grep -i -f - /var/log/maillog
sort -u
您可以进一步修改它,从而消除了对(实际上sort
没有必要 - 你可以使用uniq
)的需要
awk '/[email protected]/ {addr[$6]} END {for (a in addr) {print addr[a]}}' /var/log/maillog | grep -i -f - /var/log/maillog
这两个方法 (以及其他答案) 都对日志文件进行两次或多次搜索。看看下面的一次搜索技术是否会更快 (使用 Perl 或 Python 会更快) 会很有趣。
awk -v addr='[email protected]' '$0 ~ addr {
ids[$6]
}
{
for (id in ids) {
if ($0 ~ "^" ids[id] "$") {
print
}
}
}
$NF == "Completed" {
delete ids[$1]
}' /var/log/maillog
我还没有测试过该代码。您可能需要调整字段编号,特别是在找到“已完成”日志条目时删除 ID 的部分。它可以轻松地变成一行代码。