20

I'm writing a script that will backup data from my laptop to an Ubuntu server. To do so, I'm looking for a (ba)sh command to test if the server is available before starting the backup. something like ping on port 22 that returns a boolean.

How can I do this?

Jeff Schaller
  • 66,199
  • 35
  • 114
  • 250
Amo__
  • 303
  • 1
  • 2
  • 4

6 Answers6

30

Like this:

nc -z hostname 22 > /dev/null
echo $?

If it's 0 then it's available. If it's 1 then it's not.

bahamat
  • 38,658
  • 4
  • 70
  • 103
16

Use netcat:

nc -z localhost 22

From the manpage

 -z      Specifies that nc should just scan for listening daemons,
         without sending any data to them.
chris
  • 1,142
  • 6
  • 13
  • Damn! You beat me to it. – bahamat Feb 02 '11 at 20:23
  • 2
    thanks, didn't know nc , i was wondering why `nc -z -w 2 192.168.0.123` ( -w is the timeout option, in seconds ) does not timeout :| – Amo__ Feb 02 '11 at 23:12
  • You need to specify a port too. nc -z -w 2 192.168.0.123 22 works as expected. – chris Feb 03 '11 at 07:36
  • +1 for the `z` into. whoever you scan still can get info of who did the scan only without providing the `identification string` – amrx Sep 11 '16 at 20:37
7

Alternate:

nc -vzw 1 hostname 22
Mr. Pundir
  • 179
  • 1
  • 3
  • this should be selected answer, without `-w` option `nc` will be stuck forever on Ubuntu – Alex Jones Jan 21 '19 at 10:10
  • Bool can be used like => `nc -zw 2 examplehost.com 22 && { echo "You can call your backup function" ; } || { echo "SSH Unavailable" ; }` – Mr. Pundir Feb 23 '19 at 11:38
  • It's a very fine use of netcat .. however beware that not all ssh servers listen on port 22, and this may be reflected in the local /etc/ssh/ssh_config file. – stevea Feb 12 '23 at 08:31
6

What about

MACHINE=192.168.0.8
exec 3>/dev/tcp/${MACHINE}/22
if [ $? -eq 0 ]
then
    echo "SSH up"
else
    echo "SSH down"
fi
  • Don't always assume that it's Linux. His laptop may be a Mac. And Debian disables `/dev/tcp`. Ubuntu being Debian derived may as well (but I have no specific knowledge). But if `/dev/tcp` is available, then yes this is perfectly valid. – bahamat Feb 02 '11 at 20:35
  • thx for your feedback, i've wrote it on a Mac. –  Feb 02 '11 at 20:49
  • thanks, even if `exec 3>/dev/tcp/${HOST}/22` looks really "bizarre" – Amo__ Feb 02 '11 at 23:17
  • 2
    This is the only answer that doesn't require to install additional packages. – Chen A. Oct 23 '17 at 13:14
  • Works great for my use case in Mac and Manjaro (Arch Linux) – JeanLescure Aug 25 '20 at 18:10
0
ssh hostname exit 2>/dev/null ; echo $?

This actually creates a connection and performs authentication. Also it does not rely on the port 22 assumption which is sometimes false.

stevea
  • 316
  • 1
  • 6
0

I improved Steveas answer by adding a timeout (here 2 secs):

ssh -o ConnectTimeout=2 -p <port> <hostname> exit 2>/dev/null ; echo $?

If port is the default 22 then you can run just:

ssh -o ConnectTimeout=2 <hostname> exit 2>/dev/null ; echo $?

Without timeout ssh may wait a long time.

Using ssh instead of nc has a big advantage: It checks that answering daemon is ssh and not just any daemon. Successful "ssh ping" with ssh most likely indicates that the real ssh connection will succeed.

NOTE also that there is available app called ssh-ping. It is part of ssh-tools

Sotto Voce
  • 3,664
  • 1
  • 8
  • 21