Linux command to wait for a SSH server to be up

Solution 1:

I don't have a host that I can ssh to and control whether it's up or not, but this should work:

while ! ssh <ip>
do
    echo "Trying again..."
done

Or a shell script that is more explicit:

#!/bin/sh

ssh $1
while test $? -gt 0
do
   sleep 5 # highly recommended - if it's in your local network, it can try an awful lot pretty quick...
   echo "Trying again..."
   ssh $1
done

Save it as (say) waitforssh.sh and then call it with sh waitforssh.sh 192.168.2.38

Solution 2:

Something simple like this does the job, waiting 5 seconds between attempts and discarding STDERR

until ssh <host> 2> /dev/null
  do
    sleep 5
  done

Solution 3:

function hurryup () { 
    until ssh -o ConnectTimeout=2 "$1"@"$2"
        do sleep 1
    done
}
hurryup root "10.10.0.3"

-o ConnectTimeout=2 is a slightly hacky way of getting around not responding to network packets, reporting ssh: connect to host 10.10.0.3 port 22: Operation timed out until it's responsive.

Then, when the host responding to network packets, the 1 second sleep with happen in-between ssh: connect to host 10.10.0.3 port 22: Connection refused as we wait for ssh to come up.


Solution 4:

This is a 'ping_ssh' script I'm using. It handles timeout cases, fast success, and won't prompt for passwords or be fooled by the port being open but not responding as with 'nc' based solutions. This combines several answers found on various stackoverflow related sites.

#!/usr/bin/bash
HOST=$1
PORT=$2
#HOST="localhost"
#PORT=8022
if [ -z "$1" ]
  then
    echo "Missing argument for host."
    exit 1 
fi

if [ -z "$2" ]
  then
    echo "Missing argument for port."
    exit 1 
fi
echo "polling to see that host is up and ready"
RESULT=1 # 0 upon success
TIMEOUT=30 # number of iterations (5 minutes?)
while :; do 
    echo "waiting for server ping ..."
    # https://serverfault.com/questions/152795/linux-command-to-wait-for-a-ssh-server-to-be-up
    # https://unix.stackexchange.com/questions/6809/how-can-i-check-that-a-remote-computer-is-online-for-ssh-script-access
    # https://stackoverflow.com/questions/1405324/how-to-create-a-bash-script-to-check-the-ssh-connection
    status=$(ssh -o BatchMode=yes -o ConnectTimeout=5 ${HOST} -p ${PORT} echo ok 2>&1)
    RESULT=$?
    if [ $RESULT -eq 0 ]; then
        # this is not really expected unless a key lets you log in
        echo "connected ok"
        break
    fi
    if [ $RESULT -eq 255 ]; then
        # connection refused also gets you here
        if [[ $status == *"Permission denied"* ]] ; then
            # permission denied indicates the ssh link is okay
            echo "server response found"
            break
        fi
    fi
    TIMEOUT=$((TIMEOUT-1))
    if [ $TIMEOUT -eq 0 ]; then
        echo "timed out"
        # error for jenkins to see
        exit 1 
    fi
    sleep 10
done