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)示例将会有很大的帮助。
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)