Bash – Have Bash script wait for status message before continuing

bashlogspipesearchselenium

I'm firing up Selenium server with a bash script and as you can see from the timestamps on the log below, it takes about 32 seconds for the thing to fully come online:

Feb 28, 2012 10:19:02 PM org.openqa.grid.selenium.GridLauncher main
INFO: Launching a standalone server
22:19:02.835 INFO - Java: Sun Microsystems Inc. 20.0-b11
22:19:02.836 INFO - OS: Linux 2.6.32-220.4.1.el6.x86_64 amd64
22:19:02.852 INFO - v2.19.0, with Core v2.19.0. Built from revision 15849
22:19:02.988 INFO - RemoteWebDriver instances should connect to: http://127.0.0.1:4444/wd/hub
22:19:02.990 INFO - Version Jetty/5.1.x
22:19:02.992 INFO - Started HttpContext[/selenium-server/driver,/selenium-server/driver]
22:19:02.993 INFO - Started HttpContext[/selenium-server,/selenium-server]
22:19:02.993 INFO - Started HttpContext[/,/]
22:19:34.552 INFO - Started org.openqa.jetty.jetty.servlet.ServletHandler@488e32e7
22:19:34.552 INFO - Started HttpContext[/wd,/wd]
22:19:34.555 INFO - Started SocketListener on 0.0.0.0:4444
22:19:34.555 INFO - Started org.openqa.jetty.jetty.Server@7d29f3b5

Instead of using a "sleep 32" command after starting the server (to delay the script before moving on), I'd like my bash script to wait until it sees the string "Started SocketListener", and then continue. Is that possible?

Best Answer

You can use tail -f to keep reading from the file as it grows. Be careful with what you feed tail -f into. You can pipe tail -f into a filter that waits until the desired log line and quits. What won't work is if you pipe tail -f into a filter that pipes into another filter, because the intermediate filter will buffer its output. This works:

: >file.log  # create an empty log file
start-selenium-session --log-file=file.log &
{ tail -n +1 -f file.log & } | sed -n '/Started SocketListener/q'
speak-to-socket

Note that I put tail in the background. This is because when sed finds the desired line, it exits, but the pipeline keeps running as long as tail is waiting for the next line, which may not come immediately if at all¹. tail will exit when the next line comes and it receives a SIGPIPE. This may leave a stray tail process if the log is removed without any line being written to it (obtaining the PID of the tail process to kill it when sed exits would be possible but tricky).

¹ Thanks to Peter.O for pointing out the bug in an earlier version.

Related Question