Bash
tail -f 然後在匹配的字元串上退出
我正在嘗試配置一個啟動腳本,它將啟動 tomcat,監視 catalina.out 中的字元串“伺服器啟動”,然後執行另一個程序。我一直在嘗試 tail -f 與 grep 和 awk 的各種組合,但還沒有任何工作。我遇到的主要問題似乎是在 grep 或 awk 與字元串匹配後強制尾部死亡。
我已簡化為以下測試案例。
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 seconds 後退出,但是 tail 還需要 40 秒才能死掉。我理解為什麼會發生這種情況 - tail 只會在寫入管道時注意到管道已經消失,這僅在數據附加到文件時才會發生。更複雜的是,tail 將緩衝數據並將 B 和 C 字元作為單次寫入輸出(我通過 strace 確認了這一點)。我試圖用我在其他地方找到的解決方案來解決這個問題,比如使用 unbuffer 命令,但這並沒有幫助。
有人對如何使這項工作按我的期望工作有任何想法嗎?或者等待Tomcat成功啟動的想法(考慮等待TCP埠知道它已經啟動,但懷疑這會變得比我現在想要做的更複雜)。我已經設法讓它與 awk 一起在比賽中做一個“killall tail”,但我對這個解決方案不滿意。注意我試圖讓它在 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
更新
這種方式似乎也有效:
#!/bin/sh rm -f child.out ./child.sh > child.out & (tail -f child.out | grep -q B child.out)
如果您有時看到它立即退出,請嘗試添加 sleep 1,即
#!/bin/sh rm -f child.out ./child.sh > child.out & sleep 1 (tail -f child.out | grep -q B child.out)