我想configuration一个启动脚本,它将启动tomcat,监视string“Server startup”的catalina.out,然后运行另一个进程。 我一直在尝试tail -f与grep和awk的各种组合,但还没有任何工作。 我遇到的主要问题似乎是在grep或awk匹配string后迫使尾部死亡。
我简化了下面的testing用例。
test.sh is listed below: #!/bin/sh rm -f child.out ./child.sh > child.out & tail -f child.out | grep -q B child.sh is listed below: #!/bin/sh echo A sleep 20 echo B echo C sleep 40 echo D
我看到的行为是,grep在20秒后退出,但是尾巴会再花40秒死亡。 我明白为什么会发生这种情况 – tail只会注意到,在写入数据的时候pipe道已经不存在了,只有当数据被附加到文件时才会发生。 这是由尾巴是缓冲数据和输出B和C字符作为一个单一的写(我证实了这一点)的事实复合。 我试图用我在其他地方find的解决scheme来解决这个问题,例如使用unbuffer命令,但是这并没有帮助。
任何人有什么想法如何得到这个工作,我期望吗? 或者等待成功的Tomcat开始的想法(考虑等待TCP端口知道它已经开始,但是怀疑这会变得更复杂,现在我正在尝试做)。 我已经设法让awk在比赛中做“killall tail”,但是我对这个解决scheme并不满意。 注意我试图让这个在RHEL4上工作。
像这样的东西?
mkfifo child.fifo tail -f child.out > child.fifo & pid=$! grep -q B child.fifo && kill $pid
在全:
#!/bin/sh rm -f child.out ./child.sh > child.out & mkfifo child.fifo tail -f child.out > child.fifo & pid=$! grep -q B child.fifo && kill $pid rm child.fifo
似乎在20秒内运行。
$ time ./test2.sh real 0m20.156s user 0m0.033s sys 0m0.058s
UPDATE
这种方式似乎也工作:
#!/bin/sh rm -f child.out ./child.sh > child.out & (tail -f child.out | grep -q B child.out)
如果你看到它有时立即退出,尝试添加睡眠1,即
#!/bin/sh rm -f child.out ./child.sh > child.out & sleep 1 (tail -f child.out | grep -q B child.out)
所有在一条线上,用命令replace“做富”
#service tomcat6启动 #tail -f /var/log/tomcat6/catalina.out | awk'/服务器启动/ {系统(“做富”); 退出0}
失去尾巴。 既然你从一个空的child.out开始,你并不需要它,并且(正如你所发现的那样)会使事情变得复杂。 只是grep的睡眠循环中的第一个实例。
until fgrep -q "Server startup" child.out; do sleep 1; done
如果您确实需要保留尾巴,因为您并不总是从空的catalina.out开始,那么将尾巴放在循环中:
until tail child.out| fgrep -q "Server startup"; do sleep 1; done