Wait for a TCP Port to Open in a Bash Script
Wait until a TCP port accepts connections with a Bash loop that opens /dev/tcp/host/port, with no nc needed. It returns 0 once open, or 1 after the tries run out.
A script starts a service and the next step must not run before the port is listening.
wait_port() {
local host=$1 port=$2 tries=${3:-10} i
for ((i = 0; i < tries; i++)); do
(exec 3<>"/dev/tcp/$host/$port") 2> /dev/null && return 0
sleep 1
done
return 1
}
( sleep 2; exec python3 -m http.server 8123 --bind 127.0.0.1 > /dev/null 2>&1 ) &
srv=$!
wait_port 127.0.0.1 8123 10 && echo "port open after about ${SECONDS}s"
wait_port 127.0.0.1 8999 2
echo "closed port, exit status: $?"
kill "$srv"port open after about 3s
closed port, exit status: 1Bash treats a redirection to /dev/tcp/host/port as a request to open a TCP connection, and the open fails while nothing listens. The subshell around exec 3<>... makes the connection and closes it again, and 2> /dev/null hides the error message of the failed attempts. The run starts a web server after two seconds, and the function returned success after about three. A closed port, tried twice, returned 1. The feature is described under Redirections.
/dev/tcp exists only in Bash, and only when it was built with network redirections, which Debian does. Where nc -z host port is installed it does the same job in any shell. An open port does not mean the service is ready to answer, so check a health endpoint when one exists.