我正在为我的公司制作一个bash脚本,它在修补服务器时会删除服务器上的相关服务。
我正在尝试在脚本中创建一个带有jboss日志文件的while循环,并在“shutdown complete”存在时完成。
以下是我如何做到这一点的想法:
while [$SHUTDOWNSTATUS = ]; do
tail -f serverlog | grep 'Shutdown complete'
SHUTDOWNSTATUS='Shutdown complete'
done;
我想这不是最初的想法。这是我遇到困难之前的事情。循环永远不会完成,因为尾巴永远不会停止。
我正在研究“阅读”命令。这会更好地满足我的需求吗?
答案 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'