Reputation: 61
I'm running a small script to essentially poll a newly created AWS instances for SSH access. I want it to poll up to 60 seconds, which is why I am using the linux timeout
command.
I've got a small script that runs a while loop within a timeout command.
"Full" script for reference. You can assume the IP address is correct
# poll for SSH access
timeout_threshold=60
INSTANCE_IP=199.199.199.199
timeout $timeout_threshold bash -c "while true; do
ssh -oConnectTimeout=2 -oStrictHostKeyChecking=no -q ${INSTANCE_IP} exit
response_code=$?
if (( response_code == 0 )); then
echo \"Successfully connected to instance via SSH.\"
exit
else
echo \"Failed to connect by ssh. Trying again in 5 seconds...\"
sleep 5
fi
done"
The key part of the polling is
ssh -oConnectTimeout=2 -oStrictHostKeyChecking=no -q ${INSTANCE_IP} exit
response_code=$?
The problem is that the exit status (i.e. $?) is always empty, resulting in this output:
line 4: ((: == 0 : syntax error: operand expected (error token is "== 0 ")
Failed to connect by ssh. Trying again in 5 seconds...
How can I use the exit status when the commands are executed with a bash -c
command?
Upvotes: 0
Views: 226
Reputation: 141493
What happens in your script, is that $?
is expanded before bash is even run. It's always going to be zero or empty.
You could do change the quotes, from "
to '
. Remember to expand variables that you want to expand properly. Alternatively, you could just change escape $?
into \$?
.
timeout "$timeout_threshold" bash -c 'while true; do
ssh -oConnectTimeout=2 -oStrictHostKeyChecking=no -q '"${INSTANCE_IP}"' exit
response_code=$?
if (( response_code == 0 )); then
echo "Successfully connected to instance via SSH."
exit
else
echo "Failed to connect by ssh. Trying again in 5 seconds..."
sleep 5
fi
done'
Or use a function:
connect() {
# I pass the instance as the first argument
# alternatively you could export INSTANCE_IP from parent shell
INSTANCE_IP="$1"
while true; do
ssh -oConnectTimeout=2 -oStrictHostKeyChecking=no -q "$INSTANCE_IP" exit
response_code=$?
if (( response_code == 0 )); then
echo "Successfully connected to instance via SSH."
exit
else
echo "Failed to connect by ssh. Trying again in 5 seconds..."
sleep 5
fi
done
}
timeout_threshold=60
INSTANCE_IP=199.199.199.199
# function needs to be exprted to be used inside child bashs
export -f connect
timeout "$timeout_threshold" bash -c 'connect "$@"' -- "$INSTANCE_IP"
Upvotes: 1