如何在python asyncio上使用telnetlib3运行远程命令

时间:2015-11-13 18:12:15

标签: python-asyncio telnetlib

我正在尝试编写一个简单的telnet客户端,它只使用telnet在远程机器上运行一个命令。这需要在asyncio上运行,因为在该框架下同时监视其他任务。

我得到了几乎工作,使用下面的代码,我从telnet-client作为telnetlib3库的一部分进行了调整;除了它没有返回。我很难想象这protocol.waiter_closed到底是什么。

在任何情况下,我如何调整此代码,以便在远程端处理完命令后返回?

由于

#!/usr/bin/env python3
import logging

import asyncio
import telnetlib3

# just to check that connection is thrown away
class MyClient(telnetlib3.TelnetClient):
    def connection_lost(self, *args):
        print("connection lost on client {} - args={}".format(self, args))

@asyncio.coroutine
def register_telnet_command(loop, Client, host, port, command):
    transport, protocol = yield from loop.create_connection(Client, host, port)

    print("{} async connection OK for command {}".format(host, command))

    def send_command():
        EOF = chr(4)
        EOL = '\n'
        # adding newline and end-of-file for this simple example
        command_line = command + EOL + EOF
        protocol.stream.write(protocol.shell.encode(command_line))

    # one shot invokation of the command
    loop.call_soon(send_command)
    # what does this do exactly ?
    yield from protocol.waiter_closed

port = 23
hostname = "fit01"

def main():
    def ClientFactory():
        return MyClient(encoding='utf-8', shell = telnetlib3.TerminalShell)
    # create as many clients as we have hosts

    loop = asyncio.get_event_loop()
    loop.run_until_complete(
        register_telnet_command(loop, log, ClientFactory,
                                host = hostname, port = port,
                                command = "id"))
    return 0

main()

1 个答案:

答案 0 :(得分:0)

抱歉,我的错误,重新定义close_connection而不调用telnetlib3.connection_lost中的代码是一个坏主意,因为这是填充waiter_closed的代码。

我应该做的

class MyClient(telnetlib3.TelnetClient):
    def connection_lost(self, *args):
        print("connection lost on client {} - args={}".format(self, args))
        super().connection_lost(*args)