-
Notifications
You must be signed in to change notification settings - Fork 9
/
wait-for-command.sh
executable file
·151 lines (129 loc) · 3.4 KB
/
wait-for-command.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#!/usr/bin/env sh
# from https://github.com/ettore26/wait-for-command
# Compare a command exit status to some given number(s) for a period of time.
CMD_NAME="${0##*/}"
CMD=""
STATUS=0
TIME=10
TIME_START=0
QUIET=0
EXIT_STATUS=1
usage() {
cat << EOF >&2
Usage: ${CMD_NAME} [-c 'COMMAND']
${CMD_NAME} [OPTION]... [-c 'COMMAND']
${CMD_NAME} [-c 'COMMAND'] [OPTION]...
${CMD_NAME} compares a command exit status to some given number(s)
for a period of time. If comparison is successfully
${CMD_NAME} returns 0, otherwise 1.
Example: ${CMD_NAME} -c 'echo > /dev/tcp/127.0.0.1/5432'
${CMD_NAME} -s 0 57 -c 'curl 127.0.0.1:5432'
${CMD_NAME} -c 'nc -z 127.0.0.1 5432' -s 0 -t 20 -q
Options:
-c, --command ['COMMAND'] execute a COMMAND.
-s, --status [NUMBER]... target exit status of COMMAND, default 0.
-t, --time [NUMBER] max time to wait in seconds, default 10.
-q, --quiet do not make any output, default false.
--help display this help.
Notice that quotes are needed after -c/--command for multi-argument
COMMANDs.
Specifying a same OPTION more than once overrides the previews.
So "${CMD_NAME} -c 'nothing' -c 'curl 127.0.0.1:5432'" will be
the same as "${CMD_NAME} -c 'curl 127.0.0.1:5432'".
It does not apply to option -q/--quiet.
EOF
exit 0
}
output() {
if [ "${QUIET}" -ne 1 ]; then
printf "%s\n" "$*" 1>&2;
fi
}
process_command() {
while [ "$#" -gt 0 ]; do
case "$1" in
-c | --command)
# allow one shift when no arguments
if [ -n "$2" ]; then
CMD="$2"
shift 1
fi
shift 1
;;
-s | --status)
# ensure that a number is provided
if ([ "$2" -eq "$2" ]) >/dev/null 2>&1; then
unset STATUS
# ensure that a number is provided
while ([ "$2" -eq "$2" ]) >/dev/null 2>&1; do
if [ -z "${STATUS}" ]; then
STATUS="$2"
shift 1
else
STATUS="${STATUS} $2"
shift 1
fi
done
fi
shift 1
;;
-t | --time)
# ensure that a number is provided
if ([ "$2" -eq "$2" ]) >/dev/null 2>&1; then
TIME="$2"
shift 1
fi
shift 1
;;
-q | --quiet)
QUIET=1
shift 1
;;
--help)
usage
;;
*)
output "Unknown argument: $1"
output "Try '${CMD_NAME} --help' for more information."
exit "${EXIT_STATUS}"
;;
esac
done
if [ -z "${CMD}" ]; then
output "Missing command: -c, --command ['COMMAND']"
output "Try '${CMD_NAME} --help' for more information."
exit "${EXIT_STATUS}"
fi
}
main() {
message="failed"
process_command "$@"
TIME_START=$(date +%s)
while [ $(($(date +%s)-TIME_START)) -lt "${TIME}" ]; do
($CMD) >/dev/null 2>&1 &
pid="$!"
# while both ps and time are running sleep 1s
while kill -0 "${pid}" >/dev/null 2>&1 &&
[ $(($(date +%s)-TIME_START)) -lt "${TIME}" ]; do
sleep 1
done
# gets CMD status
kill "${pid}" >/dev/null 2>&1
wait "${pid}" >/dev/null 2>&1
cmd_exit_status="$?"
# looks for equlity in CMD exit status and one of the given status
for i in $STATUS; do
if ([ "${cmd_exit_status}" -eq "${i}" ]) >/dev/null 2>&1; then
message="finished successfully"
EXIT_STATUS=0
break 2
fi
done
done
output "${CMD_NAME} ${message} after $(($(date +%s)-TIME_START)) second(s)."
output "cmd: ${CMD}"
output "target exit status: ${STATUS}"
output "exited status: ${cmd_exit_status}"
exit "${EXIT_STATUS}"
}
main "$@"