结尾tail -f以shell脚本开头

ran*_*alo 26 bash tail

我有以下内容.

  1. Java进程将日志写入stdout
  2. 一个启动Java进程的shell脚本
  3. 另一个shell脚本,它执行前一个脚本并重定向日志
  4. 我使用tail -f成功消息的命令检查日志文件.

即使我在代码中有0出口,我也无法结束这个tail -f过程.

哪个不让我的脚本完成.在Bash中有没有其他方法可以做到这一点?

代码如下所示.

function startServer() {
  touch logfile
  startJavaprocess > logfile &

  tail -f logfile | while read line 
  do
    if echo $line | grep -q 'Started'; then
      echo 'Server Started'
      exit 0
    fi
  done
}
Run Code Online (Sandbox Code Playgroud)

fal*_*tro 25

我能想出的最佳答案就是这个

  1. 在读取时超时, tail -f logfile | read -t 30 line
  2. 启动尾部--pid=$$,这样在bash-process完成时它将退出.

它将涵盖我能想到的所有情况(服务器挂起,没有输出,服务器退出,服务器正确启动).

别忘了在服务器之前启动你的尾巴.

tail -n0 -F logfile 2>/dev/null | while read -t 30 line
Run Code Online (Sandbox Code Playgroud)

-F会"读"的文件,即使它不存在(开始读它出现时).它-n0不会读取文件中已有的任何内容,因此您可以继续附加到日志文件,而不是每次都覆盖它,以及标准日志轮换.

编辑:
好的,如果你使用尾巴,那么这是一个相当粗糙的"解决方案".可能有更好的解决方案使用其他东西,但尾巴,但我得给你,尾巴让你从破裂的管道很好.一个能够处理SIGPIPE的'tee'可能会更好.使用某种"im alive"消息主动执行文件系统丢弃的java进程可能更容易等待.

function startServer() {
  touch logfile

  # 30 second timeout.
  sleep 30 &
  timerPid=$!

  tail -n0 -F --pid=$timerPid logfile | while read line 
  do
    if echo $line | grep -q 'Started'; then
      echo 'Server Started'
      # stop the timer..
      kill $timerPid
    fi
  done &

  startJavaprocess > logfile &

  # wait for the timer to expire (or be killed)
  wait %sleep
}
Run Code Online (Sandbox Code Playgroud)


Dav*_*ick 7

基于我在这里找到的答案,这就是我想出来的.

它直接处理尾部并在我们看到所需的日志输出后将其杀死.使用'pkill -P $$ tail'应确保正确的进程被终止.

wait_until_started() {
    echo Waiting until server is started
    regex='Started'
    tail logfile -n0 -F | while read line; do
            if [[ $line =~ $regex ]]; then
                    pkill -9 -P $$ tail
            fi
    done
    echo Server is started
}
Run Code Online (Sandbox Code Playgroud)


Rob*_*tie 6

根据尾部手册页,您可以在进程终止后获得尾部终止

在BASH中,您可以使用$获取上次启动的后台进程的PID!所以如果你使用bash:

tail -f --pid=$! logfile
Run Code Online (Sandbox Code Playgroud)