python - 脚本化的 ssh 命令偶尔会无限期挂起,服务器处于活动状态并接受连接
问题描述
我正在自动化一些在云中运行的测试(具体来说是GCE)。
我配置了 VM,然后使用 ssh 运行了许多设置步骤。
有时 ssh 会无限期地挂起,我终生无法弄清楚原因。
最初我使用paramiko.exec_command
,但我发现2015 年的这个问题仍未解决,所以我决定改为尝试通过 vanilla ssh 命令subprocess.run
创建 VM 后,需要一段时间才能启动并让 sshd 开始侦听。因此,我首先true
在循环中通过 ssh 运行命令,直到它成功:
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
我使用附加到ssh
命令strace
,它被困在阅读中:
$ sudo strace -p 31856
strace: Process 31856 attached
read(5,
(我不是很熟练,strace
所以我不确定此时我是否可以做任何其他事情来获取更多信息)
我知道服务器是活着的,因为我可以 ssh 到它上面,并且在运行卡住的命令之前,我的脚本成功地true
在删除服务器上运行。
问题:
- 为什么这个命令卡住了?
- 如何检测和/或防止这种情况?
解决方案
推荐阅读
- java - 如何在 Spring 验证器中拒绝 List 中的无效值?
- regex - Sed - 删除表达式需要花括号,而不是替代表达式
- reactjs - 如何将键添加到您在 React 中呈现的数组
- java - Rest Easy Multipart Form 数据获取多个文件的文件长度
- excel - Google 表格 - 一个单元格中的多个 IF、ISNUMBER、SEARCH 语句
- android - 将字节数组转换为矢量可绘制对象
- r - 我如何有条件地应用 which.min 函数
- hyperledger-fabric - 我可以更改关系中定义的参数吗
- laravel - Laravel:如何从好友列表中隐藏用户自己的个人资料?
- svg - 复制 SVG 后,SVG 在 Safari 中显示不正确