while循环读取日志文件并在字符串" shutdown完成时完成"存在

时间:2015-03-19 23:30:55

标签: bash

我正在为我的公司制作一个bash脚本,它在修补服务器时会删除服务器上的相关服务。

我正在尝试在脚本中创建一个带有jboss日志文件的while循环,并在“shutdown complete”存在时完成。

以下是我如何做到这一点的想法:

  while [$SHUTDOWNSTATUS = ]; do
  tail -f serverlog | grep 'Shutdown complete'
  SHUTDOWNSTATUS='Shutdown complete'
   done;

我想这不是最初的想法。这是我遇到困难之前的事情。循环永远不会完成,因为尾巴永远不会停止。

我正在研究“阅读”命令。这会更好地满足我的需求吗?

3 个答案:

答案 0 :(得分:1)

执行此操作的一种方法是将日志文件重定向到文件描述符,然后读取文件描述符,直到日志文件中出现“Shutdown complete”。然后终止循环。一个例子是:

#!/bin/bash

lfn=${1:-dat/jboss.log}     # logfile (default: dat/jboss.log for test)

## test log is readable
[ -r "$lfn" ] || {
    printf "error: file '%s' is not readable.\n" "$lfn"
    exit 1
}

## redirect log to fd 3 and read until "Shutdown complete"
while :; do

    read -r -u 3 line
    if [[ $line =~ "Shutdown complete" ]]; then
        sdstatus=complete
        break
    else
        sleep 5 # adjust sleep as needed
    fi

done 3< "$lfn"  # temporary redirection of $lfn to 3

printf "Shutdown %s\n" $sdstatus

exit 0

示例

$ echo "line 1" > dat/jboss.log

$ cat dat/jboss.log
line 1

$ bash shutdown.sh &
[1] 17446

$ echo "patch applied, Shutdown complete" >> dat/jboss.log
$ Shutdown complete

[1]+  Done                    bash shutdown.sh

$ cat dat/jboss.log
line 1
patch applied, Shutdown complete

注意:由于使用了子字符串比较运算符=~,因此这是一个Bash解决方案。

答案 1 :(得分:1)

避免重新读取日志文件(或者至少尽快完成)的一种方法是记住上一次循环迭代的文件大小,并跳过那么多字节:

while :; do
    size=$(stat -c "%s" serverlog)
    new_text=$(dd if=serverlog bs="$old_size" skip=1 2>/dev/null)
    if [[ -n $new_text ]]; then
        echo "${new_text%%Shutdown complete*}
        [[ $new_text == *"Shutdown complete"* ]] && break
        old_size=$size
    fi
    sleep 0.5s
done

答案 2 :(得分:0)

我觉得应该有比这更好的想法,但我无法想到一个。

只需循环(具有睡眠延迟),直到文件上的grep返回true。 (不幸的是,这意味着每个循环重新读取整个文件,但避免更复杂。)

while ! grep -q 'Shutdown complete' serverlog; do
    sleep 5s
done
echo 'Shutdown complete'