#!/usr/bin/env sh WAITFOR_TIMEOUT=${WAITFOR_TIMEOUT:-15} WAITFOR_QUIET=${WAITFOR_QUIET:-0} echoerr() { if [ "$WAITFOR_QUIET" -ne 1 ]; then printf "%s\n" "$*" 1>&2; fi } usage() { exitcode="$1" cat <&2 usage: wait-for host:port [-t timeout] [-- command args] Synchronize services like containers and wait for readiness. optional arguments: -q | --quiet Do not output any status messages -t WAITFOR_TIMEOUT | --timeout=timeout Timeout in seconds, zero for no timeout -- COMMAND ARGS Execute command with args after the test finishes USAGE exit "$exitcode" } wait_for() { for _ in $(seq "$WAITFOR_TIMEOUT"); do if [ "$HAS_NC" = 1 ]; then nc -w 1 -z "$WAITFOR_HOST" "$WAITFOR_PORT" >/dev/null 2>&1 elif [ "$HAS_BASH" = 1 ]; then # shellcheck disable=SC3025 bash -c "/dev/null 2>&1 fi result=$? if [ $result -eq 0 ]; then if [ $# -gt 0 ]; then exec "$@" fi exit 0 fi sleep 1 done echo "error: operation timed out" >&2 exit 1 } while [ $# -gt 0 ]; do case "$1" in *:*) WAITFOR_HOST=$(printf "%s\n" "$1" | cut -d : -f 1) WAITFOR_PORT=$(printf "%s\n" "$1" | cut -d : -f 2) shift 1 ;; -q | --quiet) WAITFOR_QUIET=1 shift 1 ;; -t) WAITFOR_TIMEOUT="$2" if [ "$WAITFOR_TIMEOUT" = "" ]; then break; fi shift 2 ;; --timeout=*) WAITFOR_TIMEOUT="${1#*=}" shift 1 ;; --) shift break ;; --help) usage 0 ;; *) echoerr "unknown argument: $1" usage 1 ;; esac done if [ -x "$(command -v nc)" ]; then HAS_NC=1 fi if [ -x "$(command -v bash)" ]; then HAS_BASH=1 fi if [ "$HAS_NC" != 1 ] && [ "$HAS_BASH" != 1 ]; then echoerr "error: netcat or bash is required for wait-for to run" exit 1 fi if [ "$WAITFOR_HOST" = "" ] || [ "$WAITFOR_PORT" = "" ]; then echoerr "error: you need to provide a host and port to test" usage 2 fi wait_for "$@"