【问题标题】:Shell script to read log file from the last read line从最后读取行读取日志文件的 Shell 脚本
【发布时间】:2019-07-26 10:54:04
【问题描述】:

我的要求是使用 cron 作业中的 shell 脚本读取正在不断更新的服务器日志(相对较大)文件。如果找到字符串,我将阅读直到最后一个可用行以查找字符串和电子邮件。下次 cron 作业开始时,作业应从上次完成的行或位置读取。任何建议我如何在 shell 脚本中执行此操作。

【问题讨论】:

  • 您必须将文件位置保存到临时文件,然后从该文件位置开始读取。

标签: shell unix scripting sh


【解决方案1】:

以下内容可以帮助您入门:

tail -f your_file | while read line
do case "$line" in
        *"string_to_search"*) echo "" | mutt -s "Guilty string found" a_mail@mail.com       
;;
   esac
done 

【讨论】:

  • 我会选择 grep tail -f your_file | grep --line-buffered "string_to_search" | ... rest of the script。但是,操作请求Next time when the cron job starts the job should read from the line or position where it was last finished. 存在问题
  • @Kamil 同意,虽然我认为在每种情况下采取适当的措施时集成更多要搜索的字符串会更容易(当然,如果因情况而异)
【解决方案2】:

我使用timeout 超时tail 并使用一些保存文件来保存我们解析的行位置:

# statefile where we save the number of parsed already lines
statefile=/tmp/statefile.txt

# initialize count variable - to zero, or from statefile
if [ -e "$statefile" ]; then
    count=$(<"$statefile")
else
    count=0
fi

# we timeout for 1 seconds outputting the lines
# the better timeout would be like 10 seconds for big file
# the `tail` command needs to jump `$count` lines inside the input file
timeout 1 tail -n +$count input_log_file |
# tee is used to pass the input to the updating part
tee >(
     # read number of parsed lines with `wc -l`
     # increment the count of parsed lines and save to statefile
     echo $(( count + $(wc -l) )) >"$statefile"
) |
# grep for the searched string
grep --line-buffered string_to_search |
# do the action if string_to_search is found
do_some_action_example_send_mail

【讨论】:

  • tail -n +10 在有 10 行的文件上(第一次已经 10 行)将显示已经处理的第 10 行。
  • 不是必须的,但请注意:日志有一天会被重置。 tail 将扫描稀薄的空气。
  • 那么脚本应该如何知道日志是否被重置呢?您需要提供一种方法来以某种方式了解这一点。
猜你喜欢
  • 2021-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-06
  • 2014-02-24
相关资源
最近更新 更多