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.

Any idea on how to do it?

ssh -o ConnectTimeout=10  <hostName>

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

| improve this answer | |
  • 4
    ConnectTimeout only sets a timeout on the connection setup, right? – Aurélien Ooms Sep 12 '14 at 14:23
  • 11
    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. – Ferry Boender Oct 11 '16 at 18:37

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.

| improve this answer | |
  • 12
    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. – Dolph Oct 21 '15 at 14:42
  • 9
    It is good to point out the possible security implications of -o StrictHostKeyChecking=no. However, it will prevent the script from hanging during execution. – Doug Oct 22 '15 at 0:48
  • 2
    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. – johndodo Feb 18 '16 at 12:10
  • 2
    Updated my answer. From my experience, it can cause some clients to hang. – Doug Feb 21 '16 at 15:40

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
| improve this answer | |
  • 5
    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 ). – larcher Jul 7 '16 at 20:16
  • 4
    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. – James Davis Feb 5 '18 at 15:08
  • 1
    @JamieDavis what about ssh user@server 'timeout 5s sleep 10' ? – FilipR Dec 6 '18 at 22:04
  • @FilipR this doesn't time out if the connection is never made ;) – Xerus Oct 13 at 8:49
  • "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. – Rich yesterday

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.

| improve this answer | |
  • 5
    That sounds like the opposite of what the question requests. – Davor Cubranic Feb 19 '18 at 20:05

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

 set -u
 ssh $1 "sleep 10 ; uptime" > /tmp/outputfile 2>&1 & PIDssh=$!
 while test $Count -lt 5 && ps -p $PIDssh > /dev/null
    echo -n .
    sleep 1
 echo ""

 if ps -p $PIDssh > /dev/null
    echo "ssh still running, killing it"
    kill -HUP $PIDssh
    echo "Exited"
| improve this answer | |

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 &

echo "Script ended on Feb 15, 2011, 9:20AM" > /tmp/done.txt

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

| improve this answer | |
  • 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 ? – user57421 Feb 8 '11 at 18:42
  • Well you could make that script create a file when done. I've added the comment to the answer.... grrr – Eduardo Feb 15 '11 at 15:20

Your Answer

