Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python reactor.run()之后将命令馈送到TwistedSSH的合理方法_Python_Ssh_Twisted - Fatal编程技术网

Python reactor.run()之后将命令馈送到TwistedSSH的合理方法

Python reactor.run()之后将命令馈送到TwistedSSH的合理方法,python,ssh,twisted,Python,Ssh,Twisted,伙计们,这是一个关于python twisted ssh库的问题 所有示例代码,甚至我看到的作为基于twisted.conch.ssh的ssh客户端的生产代码,都以这样的模式与服务器交互: 准备一些远程运行的命令 定义回拨 启动反应堆,然后暂停,以获得新的反馈 在reactor.run()之后,我从未发现有人试图向sshd发送命令,脚本只是让他们等待。我认为它将有可能分叉或产卵的东西发送命令。然而,由于twisted的优势之一是它的解复用机制,所以当作为服务器运行时,它不必分叉来处理传入的请

伙计们,这是一个关于python twisted ssh库的问题

所有示例代码,甚至我看到的作为基于twisted.conch.ssh的ssh客户端的生产代码,都以这样的模式与服务器交互:

  • 准备一些远程运行的命令
  • 定义回拨
  • 启动反应堆,然后暂停,以获得新的反馈
在reactor.run()之后,我从未发现有人试图向sshd发送命令,脚本只是让他们等待。我认为它将有可能分叉或产卵的东西发送命令。然而,由于twisted的优势之一是它的解复用机制,所以当作为服务器运行时,它不必分叉来处理传入的请求。我可以说,不使用fork(作为客户机脚本)向服务器连续发送请求是合理的要求吗

有什么想法吗


蒂娅。

你想把一个方形的钉子插进一个圆形的洞里。Twisted中的所有内容都是异步的,因此您必须以不同的方式考虑事件的顺序。你不能说“这里有10个操作要一个接一个地运行”,这是连续思考


在Twisted中,发出第一个命令并注册一个回调,该回调将在完成时触发。当发生回调时,发出第二个命令并注册一个回调,该回调将在完成时触发。依此类推。

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

这一点非常简单:

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

reactor.callWhenRunning(f)
另一种方法是使用定时事件,尽管可能没有理由这样做,而不是在运行时使用
call

reactor.callLater(0, f)
您还可以使用底层API,该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."
from twisted.application.service import Application

from thatmodule import ThingDoer

application = Application("Do Things")
ThingDoer().setServiceParent(application)
然后像这样写一个.tac文件:

from twisted.application.service import Service

class ThingDoer(Service):
    def startService(self):
        print "The reactor is running now."
from twisted.application.service import Application

from thatmodule import ThingDoer

application = Application("Do Things")
ThingDoer().setServiceParent(application)
最后,您可以使用
twistd(1)
运行这个.tac文件:

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

您可以在中看到这一点,例如在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
是打开新频道时调用的事件处理程序。它向服务器发送一个请求。它返回一个延迟的,并附加一个回调。该回调是一个事件处理程序,当请求成功时(在本例中,当执行
cat
时)将调用该事件处理程序
\u cbRequest
是它附加的回调,该方法将执行下一步-向通道写入一些字节,然后关闭通道。然后是
dataReceived
事件处理程序,当通过chnanel接收字节时调用它,当通道关闭时调用
closed
事件处理程序

因此,您可以在这里看到四个不同的事件处理程序,其中一些正在启动操作,最终将触发后面的事件处理程序

因此,回到你的问题,关于一件接一件地做一件事情,如果你想一个接一个地打开两个cat通道,那么在
closed
中,事件处理程序可以打开一个新通道(而不是像本例中那样停止反应器)