在reactor.run()之后向twisted ssh提供命令的合理方法
伙计们,这是一个关于 python twins ssh lib 的问题。
我看到的所有示例代码甚至是基于twisted.conch.ssh作为ssh客户端的生产代码都是以这样的模式与服务器交互:
- 准备一些远程运行的命令;
- 定义回调;
- 启动反应堆然后暂停以获得新的反馈;
在reactor.run()之后,我从未发现有人尝试向sshd传递命令,脚本只是等待。我认为可以分叉或生成东西来发送命令。然而,由于twisted的优势之一是它的多路分解机制,因此它在作为服务器运行时不必分叉来处理传入的请求。我可以说不分叉(作为客户端脚本)不断向服务器发送请求是合理的要求吗?
对此有什么想法吗?
TIA。
Guys this is a question about python twisted ssh lib.
All sample code even production code I saw acting as a ssh client based on twisted.conch.ssh are all interacting with server in such a mode:
- prepare some commands to run remotely;
- define call backs;
- kick off reactor then suspend for new feedback;
After the reactor.run(), I never found people tried to deliver commands to sshd, the script just sit their waiting. I think it'll be possible to fork or spawn stuffs to send commands. However since one of twisted's strengths is its de-multiplexing mechanism so it doesn't have to fork to process incoming requests when running as a server. May I say it is a reasonable requirement not to fork (as a client script) to continuously send requests to server?
Any thought on this ?
TIA.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
joefis的回答基本上是合理的,但我打赌一些例子会有所帮助。首先,有几种方法可以让一些代码在反应器启动后立即运行。
这个非常简单:
另一种方法是使用定时事件,尽管可能没有理由这样做而不是使用
callWhenRunning
:您还可以使用
callWhenRunning
的底层 API code> 的实现方式是:还可以使用服务。这有点复杂,因为它涉及使用
twistd(1)
(或其他将服务系统连接到反应器的东西)。但是你可以这样编写一个类:然后像这样编写一个 .tac 文件:
最后,你可以使用
twistd(1)
运行这个 .tac 文件:当然,这只是告诉你如何做在反应堆运行后做一件事,这不完全是你所要求的。不过,这是相同的想法 - 您定义一些事件处理程序并要求通过调用该处理程序来接收事件;当它被调用时,你就可以做一些事情。同样的想法也适用于您使用 Conch 所做的任何事情。
您可以在 Conch 示例中看到这一点,例如在 sshsimpleclient.py 中我们有:
在此示例中,
channelOpen
是打开新通道时调用的事件处理程序。它向服务器发送请求。它返回一个Deferred
,并附加一个回调。该回调是一个事件处理程序,当请求成功时(在本例中,当cat
被执行时)将被调用。_cbRequest
是它附加的回调,该方法执行下一步 - 向通道写入一些字节,然后关闭它。然后是 dataReceived 事件处理程序,当通过通道接收到字节时调用该事件处理程序,以及关闭通道时调用的 close 事件处理程序。因此,您可以在这里看到四个不同的事件处理程序,其中一些正在启动操作,最终将触发稍后的事件处理程序。
因此,回到关于做一件又一件事情的问题,如果您想打开两个猫通道,一个接一个,那么在
close
事件处理程序中可以打开一个新通道(而不是停止反应器,如本例所示)。joefis' answer is basically sound, but I bet some examples would be helpful. First, there are a few ways you can have some code run right after the reactor starts.
This one is pretty straightforward:
Another way is to use timed events, although there's probably no reason to do it this way instead of using
callWhenRunning
:You can also use the underlying API which
callWhenRunning
is implemented in terms of:You can also use services. This is a bit more involved, since it involves using using
twistd(1)
(or something else that's going to hook the service system up to the reactor). But you can write a class like this:And then write a .tac file like this:
And finally, you can run this .tac file using
twistd(1)
:Of course, this only tells you how to do one thing after the reactor is running, which isn't exactly what you're asking. It's the same idea, though - you define some event handler and ask to receive an event by having that handler called; when it is called, you get to do stuff. The same idea applies to anything you do with Conch.
You can see this in the Conch examples, for example in sshsimpleclient.py we have:
In this example,
channelOpen
is the event handler called when a new channel is opened. It sends a request to the server. It gets back aDeferred
, to which it attaches a callback. That callback is an event handler which will be called when the request succeeds (in this case, whencat
has been executed)._cbRequest
is the callback it attaches, and that method takes the next step - writing some bytes to the channel and then closing it. Then there's thedataReceived
event handler, which is called when bytes are received over the chnanel, and theclosed
event handler, called when the channel is closed.So you can see four different event handlers here, some of which are starting operations that will eventually trigger a later event handler.
So to get back to your question about doing one thing after another, if you wanted to open two cat channels, one after the other, then in the
closed
event handler could open a new channel (instead of stopping the reactor as it does in this example).您正试图将方钉插入圆孔中。 Twisted 中的所有内容都是异步的,因此您必须以不同的方式考虑事件的顺序。你不能说“这里有 10 个操作要依次运行”,这是串行思维。
在 Twisted 中,您发出第一个命令并注册一个回调,该回调将在命令完成时触发。当该回调发生时,您发出第二个命令并注册一个回调,该回调将在完成时触发。等等等等。
You're trying to put a square peg in a round hole. Everything in Twisted is asynchronous, so you have to think about the sequence of events differently. You can't say "here are 10 operations to be run one after the other" that's serial thinking.
In Twisted you issue the first command and register a callback that will be triggered when it completes. When that callback occurs you issue the 2nd command and register a callback that will be triggered when that completes. And so on and so on.