我想检查 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
-W
mawk
-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"}'