You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用pexpect批量登服务器时遇TypeError:'spawn'对象不可下标访问

问题分析

错误根源是变量名重复覆盖:

  • 初始时ssh是get_credential()返回的元组(存储用户名和密码)
  • 第一次循环中,你将ssh重新赋值为pexpect.spawn()创建的会话对象
  • 第二次循环执行ssh[0]时,ssh已经是不可下标访问的spawn类型,因此抛出TypeError
修复方案

把循环中表示SSH会话的变量名改成与初始凭证变量不同的名称,避免覆盖原始的凭证元组。

修改后的完整代码:

import getpass
import pexpect
import sys


def get_credential():
    """Prompt user for ADS username and password"""
    username = getpass.getuser()
    print("[#] Connecting ADSuser as: [{}] ".format(username))
    password = getpass.getpass(" Enter ADS Password: ")
    return username, password


# 用ssh_cred存储凭证,避免和后续会话变量冲突
ssh_cred = get_credential()
print(ssh_cred)
password = ssh_cred[1]
print(password)

server = ["server1", "server2"]

for host in server:
    host_clean = host.strip()
    print(host_clean)
    ssh_command = f"ssh {ssh_cred[0]}@{host_clean}"
    print(ssh_command)
    # 改用ssh_session表示会话对象
    ssh_session = pexpect.spawn(ssh_command, timeout=5)
    ssh_session.expect('Password:')
    ssh_session.sendline(password)
    ssh_session.expect(r'\$')
    ssh_session.sendline('ls')  # 执行ls命令
    print(f"output from {host_clean}:")
    # 捕获ls命令的输出
    ssh_session.expect(r'\$')
    print(ssh_session.before.decode())
    ssh_session.close()

# 访问密码仍使用原始凭证变量
print(ssh_cred[1])
额外优化点
  • 提取host.strip()为变量host_clean,避免重复调用
  • 调整expect顺序,确保准确捕获ls命令的输出
  • 移除冗余的ssh.logfile = sys.stdout(若需要实时打印会话日志,可保留并调整放置位置)

内容的提问来源于stack exchange,提问作者bprat3

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 07:43:26