使用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
相关产品推荐
相关产品推荐

