2010-06-23 4 views
3

얘들 아 이건 파이썬 트위스트 ssh lib에 관한 질문입니다.reactor.run() 후 twisted ssh에 명령을 보내는 건전한 방법

내가 twisted.conch.ssh 기반의 ssh 클라이언트 역할을 보았다에도 생산 코드는 이러한 모든 모드에서 서버와 상호 작용하는 모든 샘플 코드 :

  • 원격으로 실행하는 몇 가지 명령을 준비;
  • 콜백을 정의합니다.
  • 반응기를 시작한 다음 새로운 피드백을 위해 일시 ​​중지합니다.

reactor.run() 이후, 사람들이 sshd에 명령을 전달하려고 시도한 것을 결코 알지 못했지만, 스크립트는 기다리고 있습니다. 나는 명령을 보내기 위해 물건을 포크하거나 산란하는 것이 가능할 것이라고 생각한다. 그러나 트위스트의 장점 중 하나는 디 멀티플렉싱 메커니즘이므로 서버로 실행할 때 들어오는 요청을 처리하기 위해 포크 할 필요가 없습니다. 서버에 지속적으로 요청을 보내기 위해 (클라이언트 스크립트로) 포크하지 않는 것이 합당한 요구라고 할 수 있습니까?

이것에 대한 의견이 있으십니까?

TIA.

답변

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에서하는 것과 동일한 아이디어가 적용됩니다.

당신은 우리가 sshsimpleclient.py 예를 들어, Conch examples에서 볼 수 있습니다

이 예에서
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은 첨부 된 콜백이며 해당 메서드는 다음 단계를 수행합니다. 즉, 채널에 일부 바이트를 쓴 다음 닫습니다. 그런 다음 채널이 닫힐 때 호출되는 closed 이벤트 핸들러 인 이벤트 핸들러가 바이트가 chnanel을 통해 수신 될 때 호출됩니다.

여기서 네 가지 이벤트 처리기를 볼 수 있습니다. 일부 이벤트 처리기는 나중에 이벤트 처리기를 트리거합니다.

두 가지 고양이 채널을 차례로 열고 싶다면 closed 이벤트 핸들러에서 다음과 같이 반응기를 중지하는 대신 새 채널을 열 수 있습니다. 이 예에서와 같습니다).

0

둥근 구멍에 사각형의 못을 넣으려고합니다. Twisted의 모든 것은 비동기식이므로 이벤트 순서에 대해 다르게 생각해야합니다. "여기에 10 개의 작업이 순차적으로 실행되어야합니다"라고 말할 수는 없습니다. 직렬 식 사고입니다.

Twisted에서는 첫 번째 명령을 실행하고 완료 될 때 트리거되는 콜백을 등록합니다. 콜백이 발생하면 두 번째 명령을 실행하고 완료 될 때 트리거되는 콜백을 등록합니다. 등등.

관련 문제