Simple polling in bash

2022-12-28
#howto

You might find your bash scripts will need to wait for something to happen before continuing on, like waiting for a server to be up and running before running tests. Here is a little function you can use in that case.

A wait_for snippet

This function waits for a test command to return 0 before moving on, polling at 1 second intervals.

wait_for() {
	local command="$@"

	while ! $command; do
		echo "[$command]: waiting..."
		sleep 1
	done

	echo "[$command]: done"
}

Here is a simple invocation:

wait_for curl --silent localhost:8000
[curl --silent localhost:8000]: waiting...
[curl --silent localhost:8000]: waiting...
[curl --silent localhost:8000]: done

Adding more control

Since the above code can block indefinitely, it helps to have a timeout. Here is a tuned-up version with additional inputs for delay and max_count.

wait_for() {
	local command="$1"
	local delay=${2-1}       # default: 1 second
	local max_count=${3-20}  # default: 20 times

	local count=1
	while ! eval "$command >/dev/null 2>&1"; do
		if [[ $count = $max_count ]]; then
			echo "[$command]: aborting after $max_count attempts"
			return 1
		fi
		count=$((count + 1))
		echo "[$command]: waiting..."
		sleep $delay
	done

	echo "[$command]: done"
}

Now you can run something like this to change the delay to 10 seconds:

wait_for "curl localhost:8000" 10

Happy coding!

~Rex