在reactor.run()之后将命令提供给扭曲的ssh的声音方法

时间:2010-06-23 13:36:13

标签: python ssh twisted

伙计们这是关于python twisted ssh lib的问题。

所有示例代码甚至生产代码我看作是基于twisted.conch.ssh的ssh客户端都在这种模式下与服务器进行交互:

  • 准备一些命令以远程运行;
  • 定义回电;
  • 启动反应堆然后暂停以获得新的反馈;

在reactor.run()之后,我从未发现人们试图向sshd发送命令,脚本只是等待他们。我认为可以分叉或产生东西来发送命令。但是,由于扭曲的优势之一是它的解复用机制,所以它不必在作为服务器运行时分叉处理传入的请求。我是否可以说不分叉(作为客户端脚本)连续向服务器发送请求是合理的要求?

有没有想过这个?

TIA。

2 个答案:

答案 0 :(得分:4)

joefis的回答基本上是合理的,但我敢打赌一些例子会有所帮助。首先,有几种方法可以在反应堆启动后立即运行一些代码。

这个很简单:

def f():
    print "the reactor is running now"

reactor.callWhenRunning(f)

另一种方法是使用定时事件,虽然可能没有理由这样做而不是使用callWhenRunning

reactor.callLater(0, f)

您还可以使用callWhenRunning实施的基础API:

reactor.addSystemEventTrigger('after', 'startup', f)

您也可以使用服务。这涉及更多,因为它涉及使用twistd(1)(或其他将服务系统连接到反应堆的其他东西)。但是你可以写一个这样的类:

from twisted.application.service import Service

class ThingDoer(Service):
    def startService(self):
        print "The reactor is running now."

然后写一个像这样的.tac文件:

from twisted.application.service import Application

from thatmodule import ThingDoer

application = Application("Do Things")
ThingDoer().setServiceParent(application)

最后,您可以使用twistd(1)运行此.tac文件:

$ twistd -ny thatfile.tac

当然,这只会告诉你如何在反应堆运行后做一件事,这不是你要求的。但是,这是相同的想法 - 您定义了一些事件处理程序并通过调用该处理程序来请求接收事件;当它被召唤时,你可以做些什么。同样的想法也适用于你用海螺做的任何事情。

您可以在Conch examples中看到这一点,例如我们在sshsimpleclient.py中看到:

class CatChannel(channel.SSHChannel):
    name = 'session'

    def openFailed(self, reason):
        print 'echo failed', reason

    def channelOpen(self, ignoredData):
        self.data = ''
        d = self.conn.sendRequest(self, 'exec', common.NS('cat'), wantReply = 1)
        d.addCallback(self._cbRequest) 

    def _cbRequest(self, ignored):
        self.write('hello conch\n')
        self.conn.sendEOF(self)

    def dataReceived(self, data):
        self.data += data

    def closed(self):
        print 'got data from cat: %s' % repr(self.data)
        self.loseConnection()
        reactor.stop()

在此示例中,channelOpen是在打开新频道时调用的事件处理程序。它向服务器发送请求。它返回一个Deferred,它附加一个回调。该回调是一个事件处理程序,它将在请求成功时被调用(在这种情况下,执行cat时)。 _cbRequest是它附加的回调,该方法采取下一步 - 将一些字节写入通道然后关闭它。然后是dataReceived事件处理程序,在通过chnanel接收字节时调用,以及closed事件处理程序,在通道关闭时调用。

因此,您可以在此处看到四个不同的事件处理程序,其中一些是启动操作,最终会触发更晚的事件处理程序。

所以回到你关于做一件又一件事的问题,如果你想一个接一个地打开两个猫通道,那么在closed事件处理程序中可以打开一个新的通道(而不是停止反应堆就像在这个例子中一样)。

答案 1 :(得分:0)

你试图把一个方形钉子放在一个圆孔里。 Twisted中的所有内容都是异步的,因此您必须以不同方式考虑事件序列。你不能说“这是一个接一个地运行的10个操作”,这是串行思考。

在Twisted中,您发出第一个命令并注册一个将在完成时触发的回调。当发生回调时,您发出第二个命令并注册一个回调,该回调将在完成后触发。等等等等。