1+ #! /usr/bin/env bash
2+ #    Use this script to test if a given TCP host/port are available
3+ 
4+ cmdname=$( basename $0 ) 
5+ 
6+ echoerr () { if  [[ $QUIET  -ne  1 ]];  then  echo  " $@ " 1>&2 ;  fi  }
7+ 
8+ usage ()
9+ {
10+     cat <<  USAGE  >&2
11+ Usage: 
12+     $cmdname  host:port [-s] [-t timeout] [-- command args] 
13+     -h HOST | --host=HOST       Host or IP under test 
14+     -p PORT | --port=PORT       TCP port under test 
15+                                 Alternatively, you specify the host and port as host:port 
16+     -s | --strict               Only execute subcommand if the test succeeds 
17+     -q | --quiet                Don't output any status messages 
18+     -t TIMEOUT | --timeout=TIMEOUT 
19+                                 Timeout in seconds, zero for no timeout 
20+     -- COMMAND ARGS             Execute command with args after the test finishes 
21+ USAGE 
22+     exit  1
23+ }
24+ 
25+ wait_for ()
26+ {
27+     if  [[ $TIMEOUT  -gt  0 ]];  then 
28+         echoerr " $cmdname : waiting $TIMEOUT  seconds for $HOST :$PORT " 
29+     else 
30+         echoerr " $cmdname : waiting for $HOST :$PORT  without a timeout" 
31+     fi 
32+     start_ts=$( date +%s) 
33+     while  : 
34+     do 
35+         if  [[ $ISBUSY  -eq  1 ]];  then 
36+             nc -z $HOST  $PORT 
37+             result=$? 
38+         else 
39+             (echo >  /dev/tcp/$HOST /$PORT ) > /dev/null 2>&1 
40+             result=$? 
41+         fi 
42+         if  [[ $result  -eq  0 ]];  then 
43+             end_ts=$( date +%s) 
44+             echoerr " $cmdname : $HOST :$PORT  is available after $(( end_ts -  start_ts)) " 
45+             break 
46+         fi 
47+         sleep 1
48+     done 
49+     return  $result 
50+ }
51+ 
52+ wait_for_wrapper ()
53+ {
54+     #  In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
55+     if  [[ $QUIET  -eq  1 ]];  then 
56+         timeout $BUSYTIMEFLAG  $TIMEOUT  $0  --quiet --child --host=$HOST  --port=$PORT  --timeout=$TIMEOUT  & 
57+     else 
58+         timeout $BUSYTIMEFLAG  $TIMEOUT  $0  --child --host=$HOST  --port=$PORT  --timeout=$TIMEOUT  & 
59+     fi 
60+     PID=$! 
61+     trap  " kill -INT -$PID " 
62+     wait  $PID 
63+     RESULT=$? 
64+     if  [[ $RESULT  -ne  0 ]];  then 
65+         echoerr " $cmdname : timeout occurred after waiting $TIMEOUT  seconds for $HOST :$PORT " 
66+     fi 
67+     return  $RESULT 
68+ }
69+ 
70+ #  process arguments
71+ while  [[ $#  -gt  0 ]]
72+ do 
73+     case  " $1 " in 
74+         * :*  )
75+         hostport=(${1//:/  } )
76+         HOST=${hostport[0]} 
77+         PORT=${hostport[1]} 
78+         shift  1
79+         ;;
80+         --child)
81+         CHILD=1
82+         shift  1
83+         ;;
84+         -q | --quiet)
85+         QUIET=1
86+         shift  1
87+         ;;
88+         -s | --strict)
89+         STRICT=1
90+         shift  1
91+         ;;
92+         -h)
93+         HOST=" $2 " 
94+         if  [[ $HOST  ==  " " ;  then  break ;  fi 
95+         shift  2
96+         ;;
97+         --host=* )
98+         HOST=" ${1#* =} " 
99+         shift  1
100+         ;;
101+         -p)
102+         PORT=" $2 " 
103+         if  [[ $PORT  ==  " " ;  then  break ;  fi 
104+         shift  2
105+         ;;
106+         --port=* )
107+         PORT=" ${1#* =} " 
108+         shift  1
109+         ;;
110+         -t)
111+         TIMEOUT=" $2 " 
112+         if  [[ $TIMEOUT  ==  " " ;  then  break ;  fi 
113+         shift  2
114+         ;;
115+         --timeout=* )
116+         TIMEOUT=" ${1#* =} " 
117+         shift  1
118+         ;;
119+         --)
120+         shift 
121+         CLI=(" $@ " 
122+         break 
123+         ;;
124+         --help)
125+         usage
126+         ;;
127+         * )
128+         echoerr " Unknown argument: $1 " 
129+         usage
130+         ;;
131+     esac 
132+ done 
133+ 
134+ if  [[ " $HOST " ==  " " ||  " $PORT " ==  " " ;  then 
135+     echoerr " Error: you need to provide a host and port to test." 
136+     usage
137+ fi 
138+ 
139+ TIMEOUT=${TIMEOUT:- 15} 
140+ STRICT=${STRICT:- 0} 
141+ CHILD=${CHILD:- 0} 
142+ QUIET=${QUIET:- 0} 
143+ 
144+ #  check to see if timeout is from busybox?
145+ #  check to see if timeout is from busybox?
146+ TIMEOUT_PATH=$( realpath $( which timeout) ) 
147+ if  [[ $TIMEOUT_PATH  =~  " busybox" ;  then 
148+         ISBUSY=1
149+         BUSYTIMEFLAG=" -t" 
150+ else 
151+         ISBUSY=0
152+         BUSYTIMEFLAG=" " 
153+ fi 
154+ 
155+ if  [[ $CHILD  -gt  0 ]];  then 
156+     wait_for
157+     RESULT=$? 
158+     exit  $RESULT 
159+ else 
160+     if  [[ $TIMEOUT  -gt  0 ]];  then 
161+         wait_for_wrapper
162+         RESULT=$? 
163+     else 
164+         wait_for
165+         RESULT=$? 
166+     fi 
167+ fi 
168+ 
169+ if  [[ $CLI  !=  " " ;  then 
170+     if  [[ $RESULT  -ne  0 &&  $STRICT  -eq  1 ]];  then 
171+         echoerr " $cmdname : strict mode, refusing to execute subprocess" 
172+         exit  $RESULT 
173+     fi 
174+     exec  " ${CLI[@]} " 
175+ else 
176+     exit  $RESULT 
177+ fi 
0 commit comments