599
|
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 |