检查是否有条件使用 awk 在日志文件中匹配

Chr*_*ris 3 shell awk shell-script tail

我想检查 auth.log 文件中是否存在已接受的 sshd 连接,并在找到时执行操作。

这是我的代码:

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

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

fre*_*ini 5

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

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

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

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

您可以使用的解决方法是使用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
Run Code Online (Sandbox Code Playgroud)

——

搜索man awkbuffer,我发现-W选项(但这是一个mawk版本...):

-W interactive

    将无缓冲写入设置为 stdout 并从 stdin 设置行缓冲读取。无论 的值如何,来自标准输入的记录都是行RS

还:

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

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