1
+ #! /usr/bin/env bash
2
+ # Use this script to test if a given TCP host/port are available
3
+
4
+ WAITFORIT_cmdname=${0##*/ }
5
+
6
+ echoerr () { if [[ $WAITFORIT_QUIET -ne 1 ]]; then echo " $@ " 1>&2 ; fi }
7
+
8
+ usage ()
9
+ {
10
+ cat << USAGE >&2
11
+ Usage:
12
+ $WAITFORIT_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 [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
28
+ echoerr " $WAITFORIT_cmdname : waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST :$WAITFORIT_PORT "
29
+ else
30
+ echoerr " $WAITFORIT_cmdname : waiting for $WAITFORIT_HOST :$WAITFORIT_PORT without a timeout"
31
+ fi
32
+ WAITFORIT_start_ts=$( date +%s)
33
+ while :
34
+ do
35
+ if [[ $WAITFORIT_ISBUSY -eq 1 ]]; then
36
+ nc -z $WAITFORIT_HOST $WAITFORIT_PORT
37
+ WAITFORIT_result=$?
38
+ else
39
+ # (echo -n > /dev/tcp/$WAITFORIT_HOST/$WAITFORIT_PORT) >/dev/null 2>&1
40
+ (curl --fail --silent $WAITFORIT_HOST :$WAITFORIT_PORT /actuator/health | grep UP) > /dev/null 2>&1
41
+ WAITFORIT_result=$?
42
+ fi
43
+ if [[ $WAITFORIT_result -eq 0 ]]; then
44
+ WAITFORIT_end_ts=$( date +%s)
45
+ echoerr " $WAITFORIT_cmdname : $WAITFORIT_HOST :$WAITFORIT_PORT is available after $(( WAITFORIT_end_ts - WAITFORIT_start_ts)) seconds"
46
+ break
47
+ fi
48
+ sleep 1
49
+ done
50
+ return $WAITFORIT_result
51
+ }
52
+
53
+ wait_for_wrapper ()
54
+ {
55
+ # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
56
+ if [[ $WAITFORIT_QUIET -eq 1 ]]; then
57
+ timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
58
+ else
59
+ timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
60
+ fi
61
+ WAITFORIT_PID=$!
62
+ trap " kill -INT -$WAITFORIT_PID " INT
63
+ wait $WAITFORIT_PID
64
+ WAITFORIT_RESULT=$?
65
+ if [[ $WAITFORIT_RESULT -ne 0 ]]; then
66
+ echoerr " $WAITFORIT_cmdname : timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST :$WAITFORIT_PORT "
67
+ fi
68
+ return $WAITFORIT_RESULT
69
+ }
70
+
71
+ # process arguments
72
+ while [[ $# -gt 0 ]]
73
+ do
74
+ case " $1 " in
75
+ * :* )
76
+ WAITFORIT_hostport=(${1//:/ } )
77
+ WAITFORIT_HOST=${WAITFORIT_hostport[0]}
78
+ WAITFORIT_PORT=${WAITFORIT_hostport[1]}
79
+ shift 1
80
+ ;;
81
+ --child)
82
+ WAITFORIT_CHILD=1
83
+ shift 1
84
+ ;;
85
+ -q | --quiet)
86
+ WAITFORIT_QUIET=1
87
+ shift 1
88
+ ;;
89
+ -s | --strict)
90
+ WAITFORIT_STRICT=1
91
+ shift 1
92
+ ;;
93
+ -h)
94
+ WAITFORIT_HOST=" $2 "
95
+ if [[ $WAITFORIT_HOST == " " ]]; then break ; fi
96
+ shift 2
97
+ ;;
98
+ --host=* )
99
+ WAITFORIT_HOST=" ${1#* =} "
100
+ shift 1
101
+ ;;
102
+ -p)
103
+ WAITFORIT_PORT=" $2 "
104
+ if [[ $WAITFORIT_PORT == " " ]]; then break ; fi
105
+ shift 2
106
+ ;;
107
+ --port=* )
108
+ WAITFORIT_PORT=" ${1#* =} "
109
+ shift 1
110
+ ;;
111
+ -t)
112
+ WAITFORIT_TIMEOUT=" $2 "
113
+ if [[ $WAITFORIT_TIMEOUT == " " ]]; then break ; fi
114
+ shift 2
115
+ ;;
116
+ --timeout=* )
117
+ WAITFORIT_TIMEOUT=" ${1#* =} "
118
+ shift 1
119
+ ;;
120
+ --)
121
+ shift
122
+ WAITFORIT_CLI=(" $@ " )
123
+ break
124
+ ;;
125
+ --help)
126
+ usage
127
+ ;;
128
+ * )
129
+ echoerr " Unknown argument: $1 "
130
+ usage
131
+ ;;
132
+ esac
133
+ done
134
+
135
+ if [[ " $WAITFORIT_HOST " == " " || " $WAITFORIT_PORT " == " " ]]; then
136
+ echoerr " Error: you need to provide a host and port to test."
137
+ usage
138
+ fi
139
+
140
+ WAITFORIT_TIMEOUT=${WAITFORIT_TIMEOUT:- 15}
141
+ WAITFORIT_STRICT=${WAITFORIT_STRICT:- 0}
142
+ WAITFORIT_CHILD=${WAITFORIT_CHILD:- 0}
143
+ WAITFORIT_QUIET=${WAITFORIT_QUIET:- 0}
144
+
145
+ # Check to see if timeout is from busybox?
146
+ WAITFORIT_TIMEOUT_PATH=$( type -p timeout)
147
+ WAITFORIT_TIMEOUT_PATH=$( realpath $WAITFORIT_TIMEOUT_PATH 2> /dev/null || readlink -f $WAITFORIT_TIMEOUT_PATH )
148
+
149
+ WAITFORIT_BUSYTIMEFLAG=" "
150
+ if [[ $WAITFORIT_TIMEOUT_PATH =~ " busybox" ]]; then
151
+ WAITFORIT_ISBUSY=1
152
+ # Check if busybox timeout uses -t flag
153
+ # (recent Alpine versions don't support -t anymore)
154
+ if timeout & > /dev/stdout | grep -q -e ' -t ' ; then
155
+ WAITFORIT_BUSYTIMEFLAG=" -t"
156
+ fi
157
+ else
158
+ WAITFORIT_ISBUSY=0
159
+ fi
160
+
161
+ if [[ $WAITFORIT_CHILD -gt 0 ]]; then
162
+ wait_for
163
+ WAITFORIT_RESULT=$?
164
+ exit $WAITFORIT_RESULT
165
+ else
166
+ if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
167
+ wait_for_wrapper
168
+ WAITFORIT_RESULT=$?
169
+ else
170
+ wait_for
171
+ WAITFORIT_RESULT=$?
172
+ fi
173
+ fi
174
+
175
+ if [[ $WAITFORIT_CLI != " " ]]; then
176
+ if [[ $WAITFORIT_RESULT -ne 0 && $WAITFORIT_STRICT -eq 1 ]]; then
177
+ echoerr " $WAITFORIT_cmdname : strict mode, refusing to execute subprocess"
178
+ exit $WAITFORIT_RESULT
179
+ fi
180
+ exec " ${WAITFORIT_CLI[@]} "
181
+ else
182
+ exit $WAITFORIT_RESULT
183
+ fi
0 commit comments