On Wed, Apr 9, 2025 at 8:48 AM A. James Lewis <ja...@fsck.co.uk> wrote:
>
> Yes, this is how I am doing it currently, but remember that once you
> cut that subshell loose, you cannot easily get a response from it and
> certainly can't pass variables back... and you are more or less forced
> to wait for a sensible timeout, even tho the actual connection might
> take a much shorter time.
>
> It also makes it extremely complex compared to a simple timeout
> feature, where multiple data could be returned from the function in a
> shorter time, and the file descriptor preserved for reuse after some of
> that data is processed.
>

FWIW, here's an extremely complex heartbeat check version workaround...

#### script begin

# $1=host $2=port [$3=timeout]
server-alive()
{
    exec 2>/dev/null
    exec 3<>/dev/tcp/"$1/$2" &
    sleep ${3:-0.5}
    ! kill -0 $! 2>/dev/null &&
        exec 2>&1 && return 0
    kill $!; exec 2>&1; return 1
}

# everything below is just sample

check()
{
    printf "$1 is "
    server-alive $1 $2 $3 &&
    echo up || echo down
}

check www.google.com 80
check 8.8.8.9 80
check 8.8.8.9 80 5

primary=8.8.8.9 secondary=www.google.com port=80
server-alive $primary $port && server=$primary ||
server-alive $secondary $port && server=$secondary
[[ "$server" ]] && echo "using server $server" ||
echo "no server currently available"
# now make new connection to server and do stuff

#### script end

Sample output:

$ ./tcp2.sh
www.google.com is up
8.8.8.9 is down
8.8.8.9 is down
using server www.google.com

Reply via email to