Reputation: 67
I have a script that looks like this, this script is checking whether my pods is in Running state or Not by redefining x on every loop.
x=$(/opt/oc get pods --selector app=${bamboo.shortPlanName} -o jsonpath='{range .items[]}{.status.phase}{"\n"}{end}')
until [ "$x" == "Running" ];
do
sleep 5
x=$(/opt/oc get pods --selector app=${bamboo.shortPlanName} -o jsonpath='{range .items[]}{.status.phase}{"\n"}{end}')
echo $x
done
But, I want to modify my current script to also support timeout, I mean after 60 second of looping, then it should be stop, or after 12 times of looping, then it should be stop. Any idea how to do that?
Upvotes: 3
Views: 2019
Reputation: 8134
For timeout after 60 seconds try this Shellcheck-clean code:
#! /bin/bash -p
readonly kOC_SLEEP_SECS=5
readonly kOC_TIMEOUT_SECS=60
initial_secs=$SECONDS
while
status=$(/opt/oc get pods --selector app=bamboo.shortPlanName \
-o jsonpath='{range .items[]}{.status.phase}{"\n"}{end}')
printf '%s\n' "$status"
[[ $status != Running ]]
do
if (( (SECONDS - initial_secs) >= kOC_TIMEOUT_SECS )); then
echo 'ERROR: Timed out' >&2
exit 1
fi
sleep -- "$kOC_SLEEP_SECS"
done
app=${bamboo.shortPlanName}
with app=bamboo.shortPlanName
because the old code was causing Bash errors. You'll need to fix it properly.echo
with printf
for printing the status.For a timeout after 12 iterations try this Shellcheck-clean variation on the code above:
#! /bin/bash -p
readonly kOC_SLEEP_SECS=5
readonly kOC_MAX_ITERS=12
oc_iters=0
while
status=$(/opt/oc get pods --selector app=bamboo.shortPlanName \
-o jsonpath='{range .items[]}{.status.phase}{"\n"}{end}')
printf '%s\n' "$status"
[[ $status != Running ]]
do
if (( ++oc_iters >= kOC_MAX_ITERS )); then
echo 'ERROR: Timed out' >&2
exit 1
fi
sleep -- "$kOC_SLEEP_SECS"
done
Upvotes: 1
Reputation: 531605
bash
provides a special variable SECONDS
that can be used as a rough timer.
SECONDS=0
while (( SECONDS < 60)); do
x=$(/opt/oc get pods --selector app=${bamboo.shortPlanName} -o jsonpath='{range .items[]}{.status.phase}{"\n"}{end}')
if [[ $x == Running ]]; then
break
fi
sleep 5
done
The expansion of SECONDS
gives you not the assigned value, but the difference between the numbers of seconds since the assignment and the assigned value. The effect is like a variable whose value is incremented by 1 each second.
Upvotes: 6
Reputation: 3451
I think trap
is the easiest way to have an accurate timeout.
Prototype:
#! /bin/bash
HALT=0
TIMEOUT=4
# Trap for SIGALRM
stop_loop() {
HALT=1
}
# Set trap
trap stop_loop SIGALRM
# The timeout goes after $TIMEOUT seconds.
{ sleep $TIMEOUT && kill -SIGALRM $$ & }
# Main loop
until false || [[ $HALT -eq 1 ]]; do
sleep 1
echo 'loop'
done
echo 'out of loop'
exit 0
In your case, this looks a something like:
HALT=0
TIMEOUT=4
stop_loop() {
HALT=1
}
trap stop_loop SIGALRM
x=$(/opt/oc get pods --selector app=${bamboo.shortPlanName} \
-o jsonpath='{range .items[]}{.status.phase}{"\n"}{end}')
{ sleep $TIMEOUT && kill -SIGALRM $$ & }
until [ "$x" == "Running" ] || [[ $HALT -eq 1 ]];
do
sleep 5
x=$(/opt/oc get pods --selector app=${bamboo.shortPlanName} \
-o jsonpath='{range .items[]}{.status.phase}{"\n"}{end}')
echo $x
done
exit 0
Upvotes: 0