File "D:\Programs\Python\Python312\Lib\telnetlib.py", line 308, in read_until i = self.cookedq.find(match) TypeError: argument should be integer or bytes-like object, not 'str'

这个错误是因为 telnetlibread_until() 方法在 Python 3 中 只接受 bytes 类型 作为参数,但你传入了一个 str 字符串。


错误原因

在 Python 3 中:

  • telnetlib 的所有数据交互(如 write()read_until())都使用 bytes 类型,而不是 str
  • 你调用了 read_until(match),但 match 是字符串(如 "#"),而它需要是 bytes(如 b"#")。

解决方案

方法 1:将 match 改为 bytes 类型

tn.read_until(b"#")  # 注意前面的 b

方法 2:如果 match 是变量,用 .encode() 转换

prompt = "#"
tn.read_until(prompt.encode('ascii'))  # 或 'utf-8'

方法 3:统一所有交互使用 bytes

# 发送命令(bytes)
tn.write(b"show version\n")

# 读取直到提示符(bytes)
output = tn.read_until(b"#")
print(output.decode('utf-8'))  # 解码为 str 打印

完整修正示例

import telnetlib

tn = telnetlib.Telnet("192.168.1.1", 23)

# 登录(全部用 bytes)
tn.read_until(b"Username:")
tn.write(b"admin\n")
tn.read_until(b"Password:")
tn.write(b"password\n")

# 发送命令并读取输出(确保 match 是 bytes)
tn.write(b"ls\n")
output = tn.read_until(b"#")  # 正确:b"#" 而不是 "#"
print(output.decode('utf-8'))  # 转为 str 打印

tn.close()

关键点

  1. telnetlib 在 Python 3 中只处理 bytes

    • write() 参数必须是 bytes(如 b"command")。
    • read_until()match 参数也必须是 bytes(如 b"#")。
  2. 如何调试

    • 检查所有字符串是否已正确编码:
      print(type(match))  # 应该是 <class 'bytes'>
      
  3. 如果设备需要 \r\n 换行符

    • 改用:
      tn.write(b"command\r\n")
      

常见问题

Q1: 为什么 Python 2 可以而 Python 3 报错?

  • Python 2 的 str 就是 bytes,但 Python 3 严格区分两者。

Q2: 如何避免反复写 b 前缀?

  • 可以定义一个辅助函数:
    def send(tn, text):
        tn.write(text.encode('utf-8'))
    
    send(tn, "show version\n")
    

Q3: 如果返回的数据需要按 str 处理?

  • 先读取 bytes,再解码:
    output = tn.read_until(b"#").decode('utf-8')
    

总结

错误场景 修正方式
read_until("#") read_until(b"#")
write("command") write(b"command")
变量字符串 prompt.encode('utf-8')

如果仍有问题,请提供你的完整代码和报错设备类型(如路由器型号),我会进一步帮你排查! 🛠️

posted @ 2025-05-15 16:32  Haloiwuhan  阅读(35)  评论(0)    收藏  举报