检查 awk 是否有条件匹配日志文件

检查 awk 是否有条件匹配日志文件

我想检查 auth.log 文件中是否已接受的 sshd 连接,并在发现任何连接时执行操作。

这是我的代码:

tail -f /var/log/auth.log | awk '{ if($0 ~ /sshd/ && $0 ~ /Accepted/) { system("echo FOUND") } }'

由于某种原因,这不会产生任何输出。有人可以解释为什么吗?

答案1

我认为您的问题与缓冲有关tail -f

~$ tail auth.log | awk '{ if($0 ~ /sshd/ && $0 ~ /Accepted/) { system("echo FOUND") } }'
FOUND
FOUND

它适用于tail,但失败于tail -f

~$ tail -f auth.log | awk '{ if($0 ~ /sshd/ && $0 ~ /Accepted/) { system("echo FOUND") } }'
^C

您可以使用的解决方法是使用while循环读取每一行tail -f

~$ tail -f auth.log | while read line
> do
>     echo $line | awk '{ if($0 ~ /sshd/ && $0 ~ /Accepted/) { system("echo FOUND")} }'
> done
FOUND
FOUND

--

搜索,我找到了这个man awk选项(但这是一个版本......):buffer-Wmawk

-W interactive

    设置对 stdout 的无缓冲写入和对 stdin 的行缓冲读取。来自 stdin 的记录都是行,无论 的值如何RS

还:

mawk接受任何这些选项的缩写,例如“ -W i”和“ -Wi” ...

~$ tail -f auth.log | awk  -Wi  '/sshd/ && /Accepted/ {system("echo FOUND")}'
FOUND
FOUND

答案2

您还可以使用 awk 的fflush()调用来刷新输出:

tail -f /var/log/auth.log | 
    awk '{ if($0 ~ /sshd/ && $0 ~ /Accepted/) { fflush(); system("echo FOUND") } }'

也就是说,你的awk复杂程度是不必要的。所有你需要的是:

tail -f /var/log/auth.log | awk '/sshd/ && /Accepted/{ fflush(); print "FOUND"}'

相关内容