Recently I needed a quick and dirty solution to achieve a synchronisation barrier between two hosts, as in:
host1> prepare-stuff && notify-host2
host2> wait-for-host1 && use-stuffWhat I came up with is this netcat solution, which makes host2 wait until host1 opens a TCP connection at specific port. After that both hosts continue executing their commands.
TLDR - the bash oneliners
# listen at 0.0.0.0:$PORT
host2> nc -l -p $PORT
# wait for netcat to listen at $HOST:$PORT and immediately close connection
# when it is achieved.
# For portability attempt netcat command with different option sets
host1> while ! nc $HOST $PORT -v -q 0 && ! nc $HOST $PORT -v -c; do sleep 0.1; done < /dev/null 2> /dev/nullExplanation
Let’s walk through the netcat flags:
-l- listen for a connection-p $PORT- listen at given port-v- be verbose (optional)-q 0- close connection 0 seconds after EOF on stdin-c- close connection after EOF (alternative flag)
By piping < /dev/null netcat receives EOF right after achieving the connection. Due to the -q 0/-c flag the connection is closed immediately and processing on both hosts can continue.
Fish functions
My shell of choice is Fish, so here are the original functions I use:
function ncnotify
while not nc $argv[1] 4444 -v -q 0 < /dev/null 2> /dev/null;
and not nc $argv[1] 4444 -v -c < /dev/null 2> /dev/null;
sleep 0.1;
end
end
function ncwait
nc -l -p 4444 $argv
endFurther work
As you can see it is quite a quick&dirty solution. It could use better error reporting than 2>/dev/null. And for production use it is much better to use a domain-specific approach for awaiting events rather than relying on flawless network connectivity.
Do you know a better or simpler approach? Let me know on Twitter!