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)) seconds"
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 " INT
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