Home Mastodon

shell: cleaner cancellable until

waitfor () {
    port=${2:-22}
    until ping -W1 -c1 "$1"; do :; done
    echo "Ping ok."
    until nc -w 1 -z "$1" "${port}"; do :; done
    echo "Port ${port} is open."
}

# Usage:
$ waitfor srv0 2223 && notify-send "Host 'srv0' is ready."

If annoyed by 'until' cancellation, a cleaner way might be:

# Run $@ until it succeeds, but allow SIGINT to cancel.
_cancellable_until () {(
    cancel="false"
    until "$@" > /dev/null; do :; done &
    trap 'kill $!; cancel="true"' INT
    wait $!
    trap - INT
    if [ $cancel = "true" ]; then
        return 1
    fi
)}

# ping $1 until it is up and port ${2:-22} is open.
waitfor () {
    port=${2:-22}
    _cancellable_until ping -W1 -c1 "$1" || return 1
    echo "Ping ok."
    _cancellable_until nc -w 1 -z "$1" "${port}" || return 1
    echo "Port ${port} is open."
}