【问题标题】:SSHCommandClientEndpoint, twisted. How to execute more than one commands?SSHCommandClientEndpoint,扭曲。如何执行多个命令?
【发布时间】:2014-03-05 11:26:44
【问题描述】:

我需要执行一些 ssh 命令。我找到了一些例子,但它是针对一个命令的,例如'pwd':

endpoint = SSHCommandClientEndpoint.newConnection(reactor, 'pwd',
                                            username, host, port,
                                            password=password,
                                            agentEndpoint=agent
                                        )
factory = MonitoringFactory()
d = endpoint.connect(factory)
d.addCallback(lambda protocol: protocol.finished)

我应该怎么做才能执行 2 个命令,例如 'pwd'、'ls'。我应该做2个端点吗?会是对的吗?但它会建立 2 个 ssh 连接,不是吗?在我看来,应该有另一种方式来做我想做的事。

【问题讨论】:

    标签: python ssh twisted endpoint


    【解决方案1】:

    使用SSHCommandClientEndpoint.existingConnection 通过单个 SSH 连接运行多个命令。

    from twisted.conch.endpoints import SSHCommandClientEndpoint
    from twisted.internet.endpoints import connectProtocol
    
    # Open a connection with a long-running command so that the connection
    # is re-usable for other commands indefinitely.
    command = b"cat"
    
    endpoint = SSHCommandClientEndpoint.newConnection(
        reactor, command, username, host, port,
        password=password, agentEndpoint=agent)
    
    connecting = connectProtocol(endpoint, Protocol())
    def connected(protocol):
        conn = protocol.transport.conn
        a = SSHCommandClientEndpoint.existingConnection(conn, b"pwd")
        b = SSHCommandClientEndpoint.existingConnection(conn, b"...")
        c = SSHCommandClientEndpoint.existingConnection(conn, b"...")
        ...
    connecting.addCallback(connected)
    ...
    

    请记住,这些命令仍然不在同一个 shell 会话中运行。因此,您可能不一定会发现像 pwd 这样的命令非常有用。

    如果你想在单个 shell 会话中运行多个命令,那么你需要使用 shell 来组合命令:

    # Open a connection with a long-running command so that the connection
    # is re-usable for other commands indefinitely.
    command = b"pwd; ls foo; cd /tmp"
    
    endpoint = SSHCommandClientEndpoint.newConnection(
        reactor, command, username, host, port,
        password=password, agentEndpoint=agent)
    
    ...
    

    【讨论】:

    • 我不确定第一个示例中是否有遗漏的内容,但是当我尝试使用 SSHCommandClientEndpoint.existingConnection() 方法时,似乎什么也没发生。由于它返回一个端点,我尝试在其上调用 connect() 以创建第二个协议实例,但是当我尝试这样做时,我得到一个异常:exceptions.AttributeError: _CommandChannel instance has no attribute 'openChannel' in tx.conch.endpoints.py line 666, Twisted v16 .1.0
    • 我想我明白了我的困惑——在你的例子中,SSHCommandClientEndpoint.existingConnection() 调用使用proto.transport 作为connection 参数,但这是不正确的。您需要使用proto.transport.conn。这可以在文档中更清楚地说明,因为这并不明显,在我意识到需要什么之前,我需要深入研究源代码并进行大量的代码自省。
    • 谢谢!对不起那个错误。我同意你的观点,这些不是最容易使用的 API。 SSH 有很多复杂性,而 Conch 无法将其全部抽象化。
    猜你喜欢
    • 1970-01-01
    • 2015-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多