简体   繁体   中英

How to use exit status inside timeout bash -c command

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 (ie $?) 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?

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"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM