Python3 telnetlib带账号密码Telnet登录后无法执行命令问题
问题描述
需要实现Telnet远程连接能力,在连接流程中输入登录用户名、密码完成身份认证,连接建立成功后执行指定操作命令。现有代码在输入密码后无法继续向下运行,未达到「完成认证、成功建立连接后下发操作命令」的预期目标。
原有问题代码如下:
import getpass import telnetlib HOST = "172.25.1.1" user = input("Enter your remote account: ") password = getpass.getpass() tn = telnetlib.Telnet(HOST) tn.read_until(b"login: ") tn.write(user.encode('utf-8') + "\n") if password: tn.read_until(b"Password: ") tn.write(password.encode('utf-8') + "\n") tn.write(b"command to be issued") print(tn.read_all())
故障原因
- 数据类型不匹配:代码中拼接发送内容时,
"\n"是普通字符串类型,和前面UTF-8编码生成的字节串无法正确拼接,发送给远端的数据包格式异常,远端无法识别到输入完成的回车标识,不会返回后续响应。 - 流程时序错误:密码发送完成后,代码没有等待远端完成认证、返回可交互的Shell提示符,直接发送操作命令,此时远端还处于认证流程中,不会处理非法输入,导致流程卡住。
- 命令格式错误:发送的操作命令末尾未添加回车换行标识,远端不会将其识别为完整的待执行命令,会持续等待用户输入完成。
- 读取逻辑错误:
tn.read_all()方法会持续读取连接数据直到连接主动断开,正常登录后Telnet连接会保持存活状态,直接调用该方法会永久阻塞。
修复方案
修正所有发送内容的格式为字节类型,补充登录成功后的提示符等待逻辑,调整命令发送和输出读取的时机,修复后可正常运行的代码如下:
import getpass import telnetlib # 配置项,根据实际连接的设备调整对应参数 HOST = "172.25.1.1" LOGIN_PROMPT = b"login: " PASSWORD_PROMPT = b"Password: " # 登录成功后远端命令行的提示符,比如Linux root用户是b"# "、普通用户是b"$ "、网络设备常见b"> " SHELL_PROMPT = b"$ " CONN_TIMEOUT = 10 user = input("Enter your remote account: ") password = getpass.getpass() # 建立连接时设置超时,避免无响应时永久卡住 tn = telnetlib.Telnet(HOST, timeout=CONN_TIMEOUT) tn.read_until(LOGIN_PROMPT, timeout=5) # 所有发送内容统一为字节格式,换行符使用字节类型的b"\n" tn.write(user.encode('utf-8') + b"\n") if password: tn.read_until(PASSWORD_PROMPT, timeout=5) tn.write(password.encode('utf-8') + b"\n") # 等待认证完成,出现Shell提示符后再发送操作命令 tn.read_until(SHELL_PROMPT, timeout=5) # 操作命令末尾必须加回车换行,替换成实际要执行的命令即可 tn.write(b"your_actual_command\n") # 读取命令输出直到再次出现Shell提示符,无需等待连接断开 output = tn.read_until(SHELL_PROMPT, timeout=CONN_TIMEOUT) print(output.decode('utf-8')) # 操作完成后主动退出关闭连接 tn.write(b"exit\n") tn.close()
适配说明
- 不同Telnet服务端的提示文本存在差异,如果运行时仍然卡住,可先手动通过Telnet连接目标设备,记录每一步的实际提示内容,替换代码中对应的提示符匹配字段即可。
- 部分老旧设备的Telnet服务需要客户端先发送一个回车才会弹出登录提示,遇到这类情况可在建立连接后先执行
tn.write(b"\n"),再等待登录提示符。 - 部分国内老旧网络设备、服务器不支持UTF-8编码,可将编码格式替换为
gbk再尝试。 - 禁止在未匹配到登录成功提示符的状态下发送操作命令,否则输入内容会被当作用户名、密码的一部分,直接导致认证失败。
内容的提问来源于stack exchange,提问作者bgardne7
相关产品推荐
相关产品推荐

