Python telnetlib3 示例

gwi*_*man 4 python telnetlib python-asyncio telnetlib3

我想了解如何在简单的场景中使用 telnetlib3。

长期存在的 telnetlib(不是 3)在https://docs.python.org/3/library/telnetlib.html有一个简单的示例,其中 python 程序连接到 telnet 服务器,然后查找提示并提供响应。人们可以很容易地看到如何将此示例扩展到不同的提示、添加超时以及添加更多提示响应步骤。

import getpass
import telnetlib

HOST = "localhost"
user = input("Enter your remote account: ")
password = getpass.getpass()

tn = telnetlib.Telnet(HOST)

tn.read_until(b"login: ")
tn.write(user.encode('ascii') + b"\n")
if password:
    tn.read_until(b"Password: ")
    tn.write(password.encode('ascii') + b"\n")

tn.write(b"ls\n")
tn.write(b"exit\n")

print(tn.read_all().decode('ascii'))
Run Code Online (Sandbox Code Playgroud)

但是,telnetlib(不是 3)已被弃用。

替代品 telnetlib3 ( https://telnetlib3.readthedocs.io/en/latest/intro.html#quick-example ) 提供了一个基于 asyncio 的示例,并且异步“shell”函数(与服务器交互)阻塞等待提示(异步的基本原理)并始终用“y”响应服务器。

import asyncio, telnetlib3

async def shell(reader, writer):
    while True:
        # read stream until '?' mark is found
        outp = await reader.read(1024)
        if not outp:
            # End of File
            break
        elif '?' in outp:
            # reply all questions with 'y'.
            writer.write('y')

        # display all server output
        print(outp, flush=True)

    # EOF
    print()

loop = asyncio.get_event_loop()
coro = telnetlib3.open_connection('localhost', 6023, shell=shell)
reader, writer = loop.run_until_complete(coro)
loop.run_until_complete(writer.protocol.waiter_closed)
Run Code Online (Sandbox Code Playgroud)

我对如何获取以这种方式构建的代码来执行更主流的任务缺乏一些线索,这些任务在(字面意思!)简单的 telnetlib (不是 3)示例中演示,其中服务器提供了一系列不同的提示,并且 python 程序就是提供相应的回应。我怀疑这部分是由于我不熟悉 asyncio 以及应该使用哪些代码模式来获取 async 函数来执行一系列步骤。

因此,看到以这种风格实现的 telnetlib(不是 3)示例将会有很大的帮助。

lar*_*sks 5

telnetlib3我认为称其为“替代品”有点言过其实telnetlib。我想它的相似之处在于它允许您编写 telnet 客户端(或服务器),但它实际上是一个完全不同的野兽。对于您在最初的示例中所做的事情telnetlib,我通常会使用pexpect(或者只是,您知道, normal expect)。

看起来PEP 594也指出Exscript作为解决方案,而且看起来telnetlib更接近于telnetlib3.


这是我编写的一个示例,用于telnetlib3连接到本地交换机、登录、发送命令enable,然后注销:

import asyncio
import telnetlib3

async def shell(reader, writer):
    rules = [
            ('User:', 'admin'),
            ('Password:', 'secret'),
            (') >', 'enable'),
            (') #', 'exit'),
            (') >', 'logout'),
            ]

    ruleiter = iter(rules)
    expect, send = next(ruleiter)
    while True:
        outp = await reader.read(1024)
        if not outp:
            break

        if expect in outp:
            writer.write(send)
            writer.write('\r\n')
            try:
                expect, send = next(ruleiter)
            except StopIteration:
                break

        # display all server output
        print(outp, flush=True)

    # EOF
    print()

async def main():
    reader, writer = await telnetlib3.open_connection('office-sw-0', 23, shell=shell)
    await writer.protocol.waiter_closed


if __name__ == '__main__':
    asyncio.run(main())
Run Code Online (Sandbox Code Playgroud)

我真的不喜欢它。我更愿意做这样的事情:

import sys
import pexpect

rules = [
    ("User:", "admin"),
    ("Password:", "secret"),
    (r"\) >", "enable"),
    (r"\) #", "exit"),
    (r"\) >", "logout"),
    (pexpect.EOF, None),
]

client = pexpect.spawn("telnet office-sw-0")

# This is so we can see what's happening.
client.logfile = sys.stdout.buffer

for expect, send in rules:
    client.expect(expect)
    if send is None:
        break
    client.sendline(send)
Run Code Online (Sandbox Code Playgroud)

  • 感谢拉尔斯克斯的回答。我没有仔细研究 Exscript,因为它的文档显示了对 Python 2.7 的要求(我使用 3.x),并且无论如何它看起来都可以满足我的需求。此外,事实证明,尽管源代码中有注释,但没有任何 API 的文档。但现在我看到 Exscript 可能也支持 Python 3.x。值得注意的是,它包含一个模块 telnetlib.py,它看起来与旧的 telnetlib.py 密切相关,并且包含一些对此效果的注释。不知道该怎么做,以及仅使用该模块本身是否是一种选择。 (2认同)