如何在脚本中使用超时进行ssh?


173

我正在执行一个脚本,该脚本通过远程主机上的无密码SSH连接。我想设置一个超时,以便如果远程主机花了无限的时间运行,我想退出该ssh会话并继续执行我的sh脚本中的其他行。

有什么想法吗?


该关闭可能与关闭此方法以减少ssh连接超时值
Murmel

如果仅将此处重定向为“在ssh会话中保留更多时间”(问题“如何增加SSH连接超时?”),那么这是错误的地方。答案是关于ssh-timeout的链接
彼得·克劳斯

Answers:


288
ssh -o ConnectTimeout=10  <hostName>

其中10是秒数。此超时仅适用于连接的创建。


4
ConnectTimeout仅在连接设置上设置超时,对吗?
的Aurelien奥姆斯

10
这实际上并不工作“远程主机正在一个无限的时间来运行”:“SSH -o ConnectTimeout = 5主机‘睡眠10’”等待10秒,不5.
轮渡Boender

109

使用-o ConnectTimeout-o BatchMode=yes -o StrictHostKeyChecking=no

ConnectTimeout阻止脚本挂起,BatchMode阻止脚本挂起,其中Host未知,是,将其添加到known_hosts,StrictHostKeyChecking自动添加指纹。

****注意****“ StrictHostKeyChecking”仅用于您信任主机的内部网络。根据SSH客户端的版本,“您确定要添加指纹”会导致客户端无限期挂起(主要是在AIX上运行的旧版本)。大多数现代版本都不会遇到此问题。如果您必须处理多个主机的指纹,我建议使用某种配置管理工具(例如puppet / ansible / chef / salt / etc)来维护known_hosts文件。


11
不仅-o StrictHostKeyChecking=no不能解决问题,而且如果您关心安全性也是一个糟糕的主意,这可能就是您首先使用SSH的原因。
2015年

9
最好指出-o StrictHostKeyChecking = no可能带来的安全隐患。但是,这将防止脚本在执行期间挂起。
道格

2
警告!!!!正如@Dolph所写,StrictHostKeyChecking=no如果您完全关心安全性,请不要使用。@Doug:脚本不会挂起-它只会坚持要求您第一次手动ssh到远程主机,因此它将了解主机。但是它将保护您免受MITM攻击。请编辑此答案以反映此内容,因为它是非常危险的建议。而且甚至没有要求。
约翰多多

2
更新了我的答案。根据我的经验,它可能会导致某些客户端挂起。
道格

50

试试这个:

timeout 5 ssh user@ip

超时执行ssh命令(带有args),如果ssh在5秒后未返回,则发送SIGTERM。有关超时的更多详细信息,请阅读此文档:http : //man7.org/linux/man-pages/man1/timeout.1.html

或者您可以使用ssh的参数:

ssh -o ConnectTimeout=3 user@ip

4
如果您在Mac上正在寻找此命令,请尝试brew install coreutils然后使用gtimeout (源:stackoverflow.com/questions/3504945/timeout-command-on-mac-os-x)。
larcher '16

3
这可能无法满足您的要求。考虑以下命令,timeout 3s ssh user@server 'sleep 5; echo blarg >> /tmp/blarg' 该命令会杀死SSH客户端上的进程,但是/ tmp / blarg仍在远程服务器上被修改。这意味着,如果您正在远程服务器上运行CPU密集型失控的作业,则会泄漏进程。
杰米·戴维斯

1
@JamieDavis ssh user @ server'timeout 5s sleep 10'怎么样?
FilipR

18

您也可以与标志连接

-o ServerAliveInterval = <秒>
因此SSH客户端每秒钟将向服务器发送一个空数据包<secs>,以保持连接有效。在Linux中,也可以在中全局设置/etc/ssh/ssh_config或在中按用户设置~/.ssh/config


4
这听起来与问题所要求的相反。
Davor Cubranic '18

1

如果所有其他timeout命令均失败(包括没有命令),则此shell脚本中的概念将起作用:

 #!/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

0

好了,您可以使用nohup运行在“非阻塞模式”下运行的任何内容。因此,您可以继续检查是否应该运行,运行或退出。

Nohup ./我的脚本可能要花很长时间才能完成
./check-if-previous-script-ran-or-exit.sh
回声“脚本于2011年2月15日上午9:20结束”> /tmp/done.txt

因此,在第二个文件中,您只需检查文件是否存在。


说得通。但是,正在运行的脚本为我提供了一些输出,该输出显示在控制台上。.如何检查我以前的脚本是运行还是退出?$?还是其他?
2011年

好了,您可以让该脚本在完成后创建一个文件。我已经在评论中添加了评论。...grrr
Eduardo
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.