在bash脚本中使用grep在日志文件上使用tail -f [英] Using tail -f on a log file with grep in bash script
问题描述
我想创建一个脚本,对正在写入的日志文件中的特定字符串进行 grep.我想取第一个结果并将其放入变量中以备后用.这将通过 SSH 连接使用,如下所示:
I'd like to create a script that greps for a specific string in a log file that is being written to. I'd like to take the first result and put that into a variable for later use. This will be used though an SSH connection like so:
ssh 'user@xxx.xxx.xxx.xxx' 'bash -s' < /usr/local/bin/checklog.sh string
普通终端中的命令
tail -f /var/log/named.log | grep $1 > $var
echo "${var}"
当我尝试上述方法时,没有输出
When I try the above method, there's no output
推荐答案
使用 while
循环可能适用于您的情况,但请注意,它不能保证捕获日志文件的每一行.考虑这样一种情况:日志编写器包含一个写出两行的操作:
Using a while
loop may work for your situation, but be aware that it's not guaranteed to catch every line of the log file. Consider a situation where the log writer includes one action that writes out two lines:
Something bad just happened:
Error xyz on line 22
很可能您的循环在执行 tail -1
操作时只会看到第二行.
It's very likely that your loop will only see the second line when it performs the tail -1
action.
不仅如此,while 循环实现意味着您在循环中旋转 CPU,不断触发 tail
命令(看看 top
而while
实现运行,而不是 tail -f
).
Not only that, but the while loop implementation means your spinning the CPU in a loop, constantly firing off tail
commands (take a look at top
while the while
implementation runs, versus a tail -f
).
这个问题有一些很好的建议,如果你只是想要在模式匹配后停止监视.(注意尾部进程的问题.)
This question has some good suggestions if you just want to stop monitoring once the pattern is matched. (Note the concerns of the tail process hanging around.)
这个怪物可能不是最优的,但它捕获每一行,在等待新行时使用最少的 CPU,在完成时终止尾部,并让您可以灵活地编写一些额外的逻辑(例如基于不同的执行操作匹配的模式):
This monstrosity is probably not optimal, but it catches every line, uses minimal CPU while waiting for new lines, terminates the tail when it's done, and gives you the flexibility to write in some extra logic (like performing actions based on different matched patterns):
watchPattern=$1
logFile=/var/log/named.log
logLine=""
while read -r logLine ; do
#Do we have a match?
if [[ "$logLine" == *"$watchPattern"* ]] ; then
#Confirmation message, written to console (for example, not needed)
echo "Found a match."
#Kill off the tail process (a bit of a hack that assumes one at a time)
kill $(ps -eo pid,command | awk -v pattern="tail -fn0 $logFile" '$0 ~ pattern && !/awk/ {print $1}')
#Get out of here
break
fi
done< <(exec tail -fn0 "$logFile")
#logLine will be the matched value
echo "match = $logLine"
这篇关于在bash脚本中使用grep在日志文件上使用tail -f的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!