2009-09-10 88 views
46

我正在创建一个bash脚本,它将登录到远程计算机并创建私钥和公钥。如何创建一个bash脚本来检查SSH连接?

我的问题是远程计算机不是很可靠,他们并不总是起来。我需要一个bash脚本来检查SSH连接是否启动。在实际创建密钥以备将来使用之前。

+2

典型地,一个运行'SSH-keygen'以生成本地机器上的密钥对,然后'SSH-复制id'复制公钥到远程机器。看来你正在做不同的事情。为什么,你的目标是什么? – ephemient 2009-09-10 19:43:38

+1

由于您明显正在改变远程机器建立连接的方式,因此可以考虑部署* mosh *。 http://mosh.mit.edu/它旨在补充不稳定连接上的SSH。我有很好的经验。 – Aeyoun 2013-08-13 11:08:21

回答

92

您可以用返回值SSH检查这给你:

$ ssh -q [email protected] exit 
$ echo $? 
255 

$ ssh -q [email protected] exit 
$ echo $? 
0 

编辑:另一种方法是使用的nmap(你不需要有键或登录-东西):

$ a=`nmap uphost -PN -p ssh | grep open` 
$ b=`nmap downhost -PN -p ssh | grep open` 

$ echo $a 
22/tcp open ssh 
$ echo $b 
(empty string) 

但是你必须grep消息(nmap不使用返回值来显示端口是否被过滤,关闭或打开)。

EDIT2:

如果你有兴趣的SSH端口的实际状态,可以替代grep openegrep 'open|closed|filtered'

$ nmap host -PN -p ssh | egrep 'open|closed|filtered' 

只要是完整的。

+0

为了完整,您能指出哪个返回码意味着成功,哪个意味着SSH失败? – 2015-09-03 13:35:43

+0

想知道如果SSH尝试只是挂在那里? – 2017-05-07 02:45:17

+1

很好的回答!然而,你没有提到只有在例如超时之后才试图进入下行主机的ssh失败。60秒 - 这对某些用途可能是禁止的。另外,如果在'〜/ .ssh/config'中定义了一个主机名,那么第一个'ssh'方法工作,而第二个'nmap'方式失败并且'无法解析'“'。 – ssc 2017-05-17 14:19:44

-2

我觉得你是想在这里解决错误的问题。你不应该试图让SSH守护进程更稳定吗?尝试运行诸如monit之类的东西,它将检查守护进程是否正在运行,如果不是,则重新启动它(给你时间来查找sshd关闭后面的根问题)。还是网络服务麻烦?试试看man ifup。整个该死的事情就像关闭你一样?那么,这是一个更大的问题...试着看看你的日志(从syslog开始),找到硬件故障或服务,关闭你的boxen(也许是温度监视器?)。

使你的脚本容错是伟大的,但你也可能想使你的Boxen有容错。

+2

Sam:有脚本检查它的有效用例。例如(像我一样):我的计算机上运行了一个cron作业,通过rsync将我的数据备份到我的主NAS。现在我在外面,甚至经常断开连接,如果连接不可用,需要重新安排时间。我的boxen运行得很好,但俗话说:它始终是电缆(又名网络) – stwissel 2012-05-22 16:15:11

2

尝试:

echo quit | telnet IP 22 2>/dev/null | grep Connected 
+1

这种方法的问题是它无法识别在ssh_config中定义的主机(即/ etc/ssh/config或〜/ .ssh/config) – 2013-03-08 07:16:40

16
ssh -q -o "BatchMode=yes" -i /home/sicmapp/.ssh/id_rsa <ID>@<Servername>.<domain> "echo 2>&1" && echo $host SSH_OK || echo $host SSH_NOK 
+1

单行输出:(ssh -q -o“BatchMode = yes”-o“ConnectTimeout = 3”[email protected]“echo 2>&1”&& echo SSH_OK || echo SSH_NOK)|尾巴-n1 – Xdg 2014-07-01 17:36:44

11

您可以使用类似这样

$(ssh -o BatchMode=yes -o ConnectTimeout=5 [email protected] echo ok 2>&1) 

这将输出 “OK”,如果SSH连接就可以了

4

补充的@Adrià Cidre响应你可以这样做:

status=$(ssh -o BatchMode=yes -o ConnectTimeout=5 [email protected] echo ok 2>&1) 

if [[ $status == ok ]] ; then 
    echo auth ok, do something 
elif [[ $status == "Permission denied"* ]] ; then 
    echo no_auth 
else 
    echo other_error 
fi