Skip to content

Instantly share code, notes, and snippets.

@9point6
Last active April 22, 2023 08:44
Show Gist options
  • Star 37 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save 9point6/ace9c7db75dc694d434d to your computer and use it in GitHub Desktop.
Save 9point6/ace9c7db75dc694d434d to your computer and use it in GitHub Desktop.
Keep retrying SSH connection until success (Useful for waiting for VMs to boot)
#!/usr/bin/env bash
# Check we've got command line arguments
if [ -z "$*" ] ; then
echo "Need to specify ssh options"
exit 1
fi
# Start trying and retrying
((count = 100))
while [[ $count -ne 0 ]] ; do
ssh $*
rc=$?
if [[ $rc -eq 0 ]] ; then
((count = 1))
fi
((count = count - 1))
done
# Print a message if we failed
if [[ $rc -ne 0 ]] ; then
echo "Could not connect to $* after 100 attempts - stopping."
fi
@gio-salvador
Copy link

gio-salvador commented Sep 6, 2016

I have a slightly different method.
My method always tries to reconnect you if you have a dirty disconnection: '~.' or 'Connection closed by remote host.'
But if you disconnect with 'CRTL+D' or with 'exit' it just disconnects and show you some info of the connections.

/bin/bash

if [ -z "$1" ]; then
echo '' && echo 'Please also provide server name as in config file...' &&
exit 1
fi

retries=0
repeat=true
today=$(date)

while "$repeat"; do
((retries+=1)) &&
echo "Try number $retries..." &&
today=$(date) &&
ssh "$1" &&
repeat=false
sleep 5
done

echo ''
echo 'Disconnected sshx after a successful login.'
echo "Total number of tries = $retries"
echo ''
echo 'Connected at:'
echo "$today"
echo ''

@perguth
Copy link

perguth commented Mar 7, 2017

@gio-salvador Your nice script in readable and a bit improved:

#!/bin/bash

if [ -z "$1" ]; then
  echo '' && echo 'Please also provide server name as in config file...' &&
  exit 1
fi

retries=0
repeat=true
today=$(date)

while "$repeat"; do
  ((retries+=1)) &&
  echo "Try number $retries..." &&
  today=$(date) &&
  ssh "$@" &&
  repeat=false
  if "$repeat"; then
    sleep 5
  fi
done

echo "Total number of tries: $retries"
echo "Last connection at: $today"

Easiest way to include in ones own system:

sudo nano /usr/local/bin/sssh
# paste the script from above & save
sudo chmod +x /usr/local/bin/sssh

# now just use the script like regular old ssh
sssh user@host

Copy link

ghost commented May 17, 2018

Nice! You could distinguish connection errors (exit code == 255) from other errors like this:

#!/usr/bin/env bash

# Check we've got command line arguments
if [ -z "$*" ] ; then
    echo "Need to specify ssh options"
    exit 1
fi

# Start trying and retrying
((count = 100)) 
while [[ $count -ne 0 ]] ; do
    ssh $*
    rc=$?
    echo ssh exit code is $rc
    if [[ $rc -ne 255 ]] ; then
        echo "Connection succeeded"
        ((count = 1))
    else
        echo "Connection error; retrying with count= " $count
    fi

    ((count = count - 1))
done

# Print a message if we failed
if [[ $rc -eq 255 ]] ; then
    echo "Could not connect to $* after 100 attempts - stopping."
fi

so that ssh host false wouldn't repeat 100 times.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment