300

I'm executing a script connecting via password-less SSH on a remote host. I want to set a timeout, so that if the remote host is taking an infinite time to run, I want to come out of that ssh session and continue other lines in my sh script.

How can I set a timeout?

2
  • This should probably be closed to be in line with the closing of a complete duplicate of this how to decrease ssh connection timeout value [closed] Commented Jan 15, 2018 at 22:01
  • 1
    If you redirected here only to "stay more time in your ssh session" (question "How to increase SSH Connection timeout?"), this is the wrong place. The answer is at this link about ssh-timeout. Commented Feb 14, 2018 at 10:04

8 Answers 8

476
ssh -o ConnectTimeout=10  <hostName>

Where 10 is time in seconds. This Timeout applies only to the creation of the connection.

Sign up to request clarification or add additional context in comments.

3 Comments

ConnectTimeout only sets a timeout on the connection setup, right?
This doesn't actually work for "the remote host is taking an infinite time to run": "ssh -o ConnectTimeout=5 host 'sleep 10'" waits for 10 seconds, not 5.
@FerryBoender It seems obvious that ConnectTimeout affects only the connection. Your example connects with success.
125

Use the -o ConnectTimeout and -o BatchMode=yes -o StrictHostKeyChecking=no .

ConnectTimeout keeps the script from hanging, BatchMode keeps it from hanging with Host unknown, YES to add to known_hosts, and StrictHostKeyChecking adds the fingerprint automatically.

**** NOTE **** The "StrictHostKeyChecking" was only intended for internal networks where you trust you hosts. Depending on the version of the SSH client, the "Are you sure you want to add your fingerprint" can cause the client to hang indefinitely (mainly old versions running on AIX). Most modern versions do not suffer from this issue. If you have to deal with fingerprints with multiple hosts, I recommend maintaining the known_hosts file with some sort of configuration management tool like puppet/ansible/chef/salt/etc.

5 Comments

Not only does -o StrictHostKeyChecking=no not address the question, but it's a terrible idea if you care about security, which might be the reason you're using SSH in the first place.
It is good to point out the possible security implications of -o StrictHostKeyChecking=no. However, it will prevent the script from hanging during execution.
WARNING!!!! As @Dolph wrote, do NOT use StrictHostKeyChecking=no if you care about security at all. @Doug: script will not hang - it will just insist that you ssh to remote host manually the first time, so it gets to know the host. But it will protect you against MITM attacks. Please edit this answer to reflect this as it is a very dangerous advice as it stands. And it wasn't even asked for.
Updated my answer. From my experience, it can cause some clients to hang.
Use -o StrictHostKeyChecking=accept-new if you really must. As per this answer
77

try this:

timeout 5 ssh user@ip

timeout executes the ssh command (with args) and sends a SIGTERM if ssh doesn't return after 5 second. for more details about timeout, read this document: http://man7.org/linux/man-pages/man1/timeout.1.html

or you can use the param of ssh:

ssh -o ConnectTimeout=3 user@ip

6 Comments

If you're looking for this command on a Mac, try brew install coreutils and then use gtimeout (source: stackoverflow.com/questions/3504945/timeout-command-on-mac-os-x ).
This may not do what you want. Consider the command timeout 3s ssh user@server 'sleep 5; echo blarg >> /tmp/blarg' This kills the process on the SSH client side, but /tmp/blarg still gets modified on the remote server. This means that if you are running a runaway CPU-intensive job on the remote server, you will leak processes.
@JamieDavis what about ssh user@server 'timeout 5s sleep 10' ?
@FilipR this doesn't time out if the connection is never made ;)
"this ... or this" should normally raise the question "why not both?" A combination of both is what I use in my own scripting. The threshold for timeout $X should be larger than the that for ssh -o ConnectTimeout=$Y (i.e. X > Y), naturally. This catches the situation where the remote machine is hanging after the connection is successfully made and you never get to your next machine in the queue.
|
31

You could also connect with flag

-o ServerAliveInterval=<secs>
so the SSH client will send a null packet to the server each <secs> seconds, just to keep the connection alive. In Linux this could be also set globally in /etc/ssh/ssh_config or per-user in ~/.ssh/config.

1 Comment

That sounds like the opposite of what the question requests.
10

just adding the following .ssh/config snippet that I use,

  ServerAliveInterval 20
  ServerAliveCountMax 5
  ConnectTimeout 10

ConnectTimeout Specifies the timeout (in seconds) used when connecting to the SSH server, instead of using the default system TCP timeout. This timeout is applied both to establishing the connection and to performing the initial SSH protocol handshake and key exchange. (from the doc)

3 Comments

Useful to add that the unit is seconds according to doc.
should I add these value into client's .ssh/config or in remote server's .ssh/config
to the user's client config that will use ssh to a remote server
4

If all else fails (including not having the timeout command) the concept in this shell script will work:

 #!/bin/bash
 set -u
 ssh $1 "sleep 10 ; uptime" > /tmp/outputfile 2>&1 & PIDssh=$!
 Count=0
 while test $Count -lt 5 && ps -p $PIDssh > /dev/null
 do
    echo -n .
    sleep 1
    Count=$((Count+1))
 done
 echo ""

 if ps -p $PIDssh > /dev/null
 then
    echo "ssh still running, killing it"
    kill -HUP $PIDssh
 else
    echo "Exited"
 fi

Comments

2

timeout 5 ssh user@machine works for me.

Comments

0

Well, you could use nohup to run whatever you are running on 'non-blocking mode'. So you can just keep checking if whatever it was supposed to run, ran, otherwise exit.

nohup ./my-script-that-may-take-long-to-finish.sh &
./check-if-previous-script-ran-or-exit.sh
echo "Script ended on Feb 15, 2011, 9:20AM" > /tmp/done.txt

So in the second one you just check if the file exists.

2 Comments

Makes sense. but, the script which is running gives me some output, which is displayed on the console.. how to check if my previous script ran or exit? $? or anything else ?
Well you could make that script create a file when done. I've added the comment to the answer.... grrr

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.