shinyb Posted November 18, 2014 Share Posted November 18, 2014 The script should read from a file the list of hosts and ports to check. Example: server-1.dev.internal:443 server-2.prod.internal:25 For each line, the script should check TCP network connectivity between the server it's running on and that host:port combination and, in case it fails, find out the reason. Possible results for a check: - Success. - DNS record does not exist. (cannot resolve hostname) - Service not running (remote host is not listening on that port) - Connection rejected (remote host is listening on that port but network connection is rejected) - Timeout (remote host is listening on that port but network connection is timing out) Script's output will consist on a list of checks, results and the time it took for each one of them. Example: server-1.dev.internal:443 | Success | 3.4s server-2.prod.internal:25 | Service not running | 0.2s Note: Script is expecting a text file and is executed as: ./script_name <path-to-file> Quote Link to comment Share on other sites More sharing options...
cooper Posted November 18, 2014 Share Posted November 18, 2014 (edited) `sed s/^/time nc\ -vz\ / <path-to-file> | sed s/:/\ /` Edit: Above but as a single command: `sed s/^\\\(\[^:\]*\\\):/time\ nc\ -vz\ \\1\ / <path-to-file>` Edited November 20, 2014 by Cooper Quote Link to comment Share on other sites More sharing options...
Sitwon Posted November 20, 2014 Share Posted November 20, 2014 Trying to emulate your example relatively closely... #!/usr/bin/env bash TIMEOUT=30 stime(){ local START="$( date +%s )" "$@" local END="$( date +%s )" TIME=$(( END - START )) } get_status(){ STATUS="$( nc -w "${TIMEOUT}" -z ${DOMAIN} ${PORT} 2>&1 && echo Success )" if [ "${STATUS}" != "Success" ]; then STATUS="${STATUS##*: }" fi } report_status(){ stime get_status echo "${STATUS} | ${TIME}s" } while read LINE ; do DOMAIN="${LINE%%:*}" # alternatively: "$( cut -d : -f 1 <<<"${LINE}" )" PORT="${LINE##*:}" # alternatively: "$( cut -d : -f 2 <<<"${LINE}" )" echo "${DOMAIN}:${PORT} | $( report_status )" done < "${1}" The output doesn't exactly match your examples, but it's pretty close. There are many potential improvements that could be made, such as testing servers in parallel rather than sequential, improving the resolution of the timer, or performing additional diagnostics on failed connections. If I get bored today I may continue poking at this and update the thread. Quote Link to comment Share on other sites More sharing options...
cooper Posted November 20, 2014 Share Posted November 20, 2014 I bow to your superior script-fu. Though wouldn't it be easier in get_status to run the nc command and then test $? to see if it was a success? Quote Link to comment Share on other sites More sharing options...
Sitwon Posted November 20, 2014 Share Posted November 20, 2014 Easier? I don't know. It would also work. I guess I could have written it like this. get_status(){ STATUS="$( nc -w "${TIMEOUT}" -z ${DOMAIN} ${PORT} 2>&1 )" if [ "$?" -eq 0 ]; then STATUS="Success" else STATUS="${STATUS##*: }" fi } Or even like this. get_status(){ STATUS="$( nc -w "${TIMEOUT}" -z ${DOMAIN} ${PORT} 2>&1 )" \ && STATUS="Success" \ || STATUS="${STATUS##*: }" } Just up to your style/preference I suppose. Quote Link to comment Share on other sites More sharing options...
shinyb Posted November 20, 2014 Author Share Posted November 20, 2014 Thanks for your responses guys, too bad nc "-z" option is not available in my centos 7; it fails with nc: invalid option -- 'z' I guess I'll have to stick with some other tool. Quote Link to comment Share on other sites More sharing options...
cooper Posted November 20, 2014 Share Posted November 20, 2014 (edited) See here for the -z problem. https://bugs.launchpad.net/percona-xtradb-cluster/+bug/1349384 Edited November 20, 2014 by Cooper Quote Link to comment Share on other sites More sharing options...
cooper Posted November 20, 2014 Share Posted November 20, 2014 Easier? I don't know. It would also work. [snip] Just up to your style/preference I suppose. I was thinking more like this get_status(){ nc -w "${TIMEOUT}" -z ${DOMAIN} ${PORT} if [ "$?" -eq 0 ]; then STATUS="Success" else STATUS="${STATUS##*: }" fi } Quote Link to comment Share on other sites More sharing options...
Sitwon Posted November 20, 2014 Share Posted November 20, 2014 I was thinking more like this get_status(){ nc -w "${TIMEOUT}" -z ${DOMAIN} ${PORT} if [ "$?" -eq 0 ]; then STATUS="Success" else STATUS="${STATUS##*: }" fi } That would not work. You need to capture the output of nc into the $STATUS variable, otherwise your else clause will just result in $STATUS=="". Quote Link to comment Share on other sites More sharing options...
cooper Posted November 20, 2014 Share Posted November 20, 2014 Oh, that's what that does... I once again humbly bow to your superior script-fu. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.