Python 脚本化ssh命令有时会无限期挂起,服务器处于活动状态并接受连接
我正在自动化一些在云中运行的测试(具体来说) 我配置VM,然后使用ssh运行许多设置步骤 有时候宋承宪会无限期地被绞死,我一辈子都不知道为什么 最初我使用了,但从2015年开始我发现这个问题仍然没有解决,所以我决定改为通过 创建VM后,需要一段时间才能启动,sshd也需要一段时间才能开始侦听。因此,我首先通过ssh在一个循环中运行命令Python 脚本化ssh命令有时会无限期挂起,服务器处于活动状态并接受连接,python,linux,ssh,Python,Linux,Ssh,我正在自动化一些在云中运行的测试(具体来说) 我配置VM,然后使用ssh运行许多设置步骤 有时候宋承宪会无限期地被绞死,我一辈子都不知道为什么 最初我使用了,但从2015年开始我发现这个问题仍然没有解决,所以我决定改为通过 创建VM后,需要一段时间才能启动,sshd也需要一段时间才能开始侦听。因此,我首先通过ssh在一个循环中运行命令true,直到它成功: retries = 6 while True: # just run 'true' on the remove server so
true
,直到它成功:
retries = 6
while True:
# just run 'true' on the remove server so if it executes successfully we know
# sshd is alive and accepting connections
cmd = ('ssh -o ConnectTimeout=10 -o StrictHostKeyChecking=no '
'-o UserKnownHostsFile=/dev/null {user}@{host} true').format(
user=user, host=host)
r = subprocess.run(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True)
if r.returncode == 0:
break
retries -= 1
if retries == 0:
raise UnableToConnect()
time.sleep(10)
成功运行true
后,我知道服务器处于活动状态并且正在接受ssh连接,因此我可以继续执行设置步骤
def run_cmd(user, host, cmd):
cmd = ('ssh -o ConnectTimeout=10 -o StrictHostKeyChecking=no '
'-o UserKnownHostsFile=/dev/null {user}@{host} {cmd}').format(
user=user, host=host, cmd=shlex.quote(cmd))
r = subprocess.run(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True)
return {
'returncode': p.returncode,
'stdout' : p.stdout.decode("utf-8").rstrip(),
'stderr' : p.stderr.decode("utf-8").rstrip(),
}
大多数情况下,一切都按预期进行,但有时ssh命令将永远不会返回,无限期地挂起
例如,我需要安装binutils
:
run_cmd(user, vm_ip_addr, 'dpkg -s binutils || sudo apt-get install -y binutils')
命令永远不会返回
$ ps -ef | grep ssh
steve 31855 ... 00:00:00 /bin/sh -c ssh -o ConnectTimeout=10 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null fred@123.123.123.123 'dpkg -s binutils || sudo apt-get install -y binutils'
steve 31856 ... 00:00:00 ssh -o ConnectTimeout=10 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null fred@123.123.123.123 dpkg -s binutils || sudo apt-get install -y binutils
我使用strace
连接到ssh
命令,它被卡在一个read中:
$ sudo strace -p 31856
strace: Process 31856 attached
read(5,
(我对strace
不是很熟练,所以我不确定在这一点上是否还有其他方法可以获得更多信息)
我知道服务器是活动的,因为我能够用ssh连接到服务器上,在运行卡住的命令之前,我的脚本成功地在remove服务器上运行了true
问题:
- 为什么这个命令被卡住了
- 我如何检测和/或防止这种情况
ServerAliveInterval
,查看manssh\u config
了解详细信息,您也可以通过-o
在cmdline上传递它;至少检测到情况并终止流程。对于正在进行的连接,没有超时,因此您必须从外部实现watchdog。当您使用ssh在远程系统上调用命令时,本地ssh实例在远程命令完成之前继续运行是正常的。您应该调查发生这种情况时远程服务器上发生的情况。我偶尔会遇到类似的问题,并强烈怀疑这是因为糟糕的网络质量,错误配置到点连接可能会导致死亡,但您的连接甚至没有正确断开(小包静静地消失了,它似乎悬在一个边缘).长话短说,也许可以尝试设置/使用:ServerAliveInterval
,查看man ssh\u config
了解详细信息,您也可以通过-o
在cmdline上传递它;至少可以检测到情况并终止进程。对于正在进行的连接,没有超时,因此您必须从外部实现watchdog。如果您需要e ssh要在远程系统上调用命令,本地ssh实例在远程命令完成之前继续运行是正常的。发生这种情况时,您应该调查远程服务器上发生了什么。