首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用bash实时读取日志

使用bash实时读取日志
EN

Ask Ubuntu用户
提问于 2022-02-27 08:03:01
回答 2查看 770关注 0票数 0

我在系统日志中有这个:

代码语言:javascript
复制
Feb 27 02:53:51 Latitude-E6430 rsyslogd: action up   7
Feb 27 02:53:51 Latitude-E6430 rsyslogd: action down B
Feb 27 02:53:51 Latitude-E6430 rsyslogd: action up   U
....etc

我想要创建一个脚本,该脚本作为一个服务全职监视日志,但我不知道如何处理这个条件。

当你逐行阅读时,把它存储在一个变量中。

2- read变量如果它在行中找到,则单词和它显示

这将是一个循环,逐行读取文件,寻找该模式的单词。

Example脚本

代码语言:javascript
复制
path_full_log="/home/full.log"


function reader_time_real(){

    while read full_log; do
        chek7=$(cat $full_log | grep "rsyslogdd" | grep 7 )
            if [[ $? = 0 ]]; then 
                echo "Found 7";

            fi

        chekB=$(cat $full_log | grep "rsyslogdd" | grep B )
            if [[ $? = 0 ]]; then 
                echo "Found B";

            fi
    done < $path_full_log
}
EN

回答 2

Ask Ubuntu用户

发布于 2022-02-28 07:59:49

你的剧本不适合做你想做的事。它只读取文件一次,但完全读取。如果循环这个,就不会只得到新的输出,这将是性能的噩梦。

另外,您对cat的使用是无用的,您可以使用regex模式使用一个固定的字符串,并将结果保存在一个不再使用的变量中。此外,您不应该使用未引用的文件名变量。

使用tail -f | grep --line-buffered

代码语言:javascript
复制
tail -fn0 "$path_full_log" \
| grep -F --line-buffered 'rsyslogdd' \
| grep -Eo --line-buffered '(7|B)' \
| while read line; do
      echo "Found $line"
  done

或者使用xargs

代码语言:javascript
复制
tail -fn0 "$path_full_log" \
| grep -F --line-buffered 'rsyslogdd' \
| grep -Eo --line-buffered '(7|B)' \
| xargs -I{} echo "Found {}"
  • tail -fn0在添加文件时读取它们的新行。
  • grep -F在该行中搜索固定字符串。
  • --line-buffered告诉grep在行进来时读取它们,而不是等待输入流的末尾,这是默认的。
  • grep -Eo搜索ERE模式(-E) (7|B),并只输出匹配的字符串(-o)。
  • while read linexargs -I{}接受该输出并对输出运行命令(此处为:echo)。
票数 4
EN

Ask Ubuntu用户

发布于 2022-02-28 08:26:20

我已经创建了下面的脚本,它每秒钟更新一次,并突出显示任何新的日志条目。它还定义了日志应该显示的区域(包括logrowslogcols变量),因此它可以在固定大小的终端窗口中使用(我在tmux中使用它)。

正如您所指出的,您可能可以修改此脚本,只突出显示符合特定条件的行。

代码语言:javascript
复制
#!/bin/bash

# Initial configuration variables
logrows=31
logcols=127

# Local function definition
printnew() {
  clear
  echo -e "\e[0;30;47m"
  hightail=$(tail -n "$logrows" /var/log/syslog | cut -b "1-$logcols")
  echo -ne "${hightail}\e[0m"
}

printdif() {
  (( newrows = logrows - logdiff ))
  clear
  normtail=$(tail -n "$logrows" /var/log/syslog | head -n "$newrows" | cut -b "1-$logcols")
  echo -n "$normtail"
  echo -e "\e[0;30;47m"
  hightail=$(tail -n "$logdiff" /var/log/syslog | cut -b "1-$logcols")
  echo -ne "${hightail}\e[0m"
}

printold() {
  clear
  normtail=$(tail -n "$logrows" /var/log/syslog | cut -b "1-$logcols")
  echo -n "$normtail"
}

# Loop every second
while true
do
  sleep 1 &

  # Read log sizes
  logsize=$(wc -l /var/log/syslog | cut -d ' ' -f1)
  (( logdiff = logsize - presize ))

  # If more than $logrows lines are new
  if (( logdiff > "$logrows" ))
  then
    printnew
    redraw=1
  # If less than $logrows lines but more than 0 lines are new
  elif (( logdiff > 0 ))
  then
    printdif
    redraw=1
  # If no lines are new
  else
    if [[ "$redraw" -eq 1 ]]
    then
      printold
      redraw=0
    fi
  fi

  presize="$logsize"
  wait # for sleep
done

脚本的编写考虑了3种场景:

  1. logrows的整个内容都是新的--所有内容都高亮显示(printnew)。
  2. 日志的一些行是新的--这些都是高亮显示的(printdif)。
  3. 没有新的日志行-没有突出显示(printold)。

免责声明:代码可能会被优化,但我通常更关注代码的可读性,而不是尽可能地精简代码。

票数 2
EN
页面原文内容由Ask Ubuntu提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://askubuntu.com/questions/1395079

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档