讓我從這開始......我根本不瞭解Python;我在圈子裏,我根本不明白。我完全接受替代和簡單的方法。Python扭曲的海螺 - 如何停止與多個連接的反應堆?
我的目標:連接到不同的服務器,在每個服務器上運行相同的命令,並且以後(如現在/不在)使用輸出來提高生產力。真棒。
我有什麼:在某處找到了一些代碼(我會試着找到一個鏈接並更新它)。我修改了一下。它連接到不同的服務器,運行相同的命令。
問題:一旦一切完成,我不知道如何停止反應堆。而我真的想要停止它不按cntrl+c
。我想我需要推遲一些事情,但我不知道在哪裏或在哪裏。我覺得像SSHChannel關閉的時候,需要以某種方式冒泡到SSHConnection,停止服務...所以交通工具可以知道怎麼了?我一直想以某種方式將每個reactor.connectTCP(server, 22, factory)
都推遲。我覺得我可能需要一個控制器類。我嘗試了這些東西,但沒有正確嘗試。也許gatherResults
可能會有所幫助,但是,我不知道該怎麼說。
from twisted.conch.ssh import transport, connection, userauth, channel, common
from twisted.internet import defer, protocol, reactor
import sys, struct
USER = 'username'
PASS = 'thisisforpersonalusesoicanstoreit!'
CMD = 'echo "merely this and nothing more"'
from twisted.python import log
import sys
log.startLogging(sys.stdout)
class ClientCommandTransport(transport.SSHClientTransport):
def __init__(self, username, password, command):
self.username = username
self.password = password
self.command = command
def verifyHostKey(self, pubKey, fingerprint):
print fingerprint
return defer.succeed(True)
def connectionSecure(self):
self.requestService(
PasswordAuth(self.username, self.password,
ClientConnection(self.command)))
class PasswordAuth(userauth.SSHUserAuthClient):
def __init__(self, user, password, connection):
userauth.SSHUserAuthClient.__init__(self, user, connection)
self.password = password
def getPassword(self, prompt=None):
return defer.succeed(self.password)
class ClientConnection(connection.SSHConnection):
def __init__(self, cmd, *args, **kwargs):
connection.SSHConnection.__init__(self)
self.command = cmd
def serviceStarted(self):
self.openChannel(CommandChannel(self.command, conn=self))
class CommandChannel(channel.SSHChannel):
name = 'session'
def __init__(self, command, *args, **kwargs):
channel.SSHChannel.__init__(self, *args, **kwargs)
self.command = command
self.data = ''
def channelOpen(self, data):
self.conn.sendRequest(
self, 'exec', common.NS(self.command), wantReply=True).addCallback(
self._gotResponse)
def _gotResponse(self, _):
self.conn.sendEOF(self)
self.loseConnection()
def dataReceived(self, data):
#self.data += data
print data
def request_exit_status(self, data):
(status,) = struct.unpack('>L', data)
# print 'exit status = ', status
class ClientCommandFactory(protocol.ClientFactory):
def __init__(self, command=CMD):
self.username = USER
self.password = PASS
self.command = command
def buildProtocol(self, addr):
protocol = ClientCommandTransport(
self.username, self.password, self.command)
return protocol
masters = ['server1','server2','server3','server4','server5']
factory = ClientCommandFactory()
for server in masters:
print server
reactor.connectTCP(server, 22, factory)
reactor.run()
我也有推遲getPage
一個http請求劇(沒有工作),但我似乎無法與電抗器和SSH連接到重新應用它。
這些都是資源,我真希望我能看得懂:
- http://twistedmatrix.com/documents/current/api/twisted.internet.defer.gatherResults.html
- http://mumak.net/stuff/twisted-disconnect.html
- Python Twisted Stopping The Reactor With Multiple Clients
- Best way to run remote commands thru ssh in Twisted?
- What is the correct way to close a Twisted conch SSH connection?
- 和所有扭曲的類定義..
與下面的一個答案......我測試了向下傳遞到工廠的參考,並最終停止在SSHChannel
closed()
校長如果工廠沒有它的數組中再連接(或任何python調用數組)。
我廠更新到現在也包括這種方法:
class ClientCommandFactory(protocol.ClientFactory):
def clientConnectionLost(self, connector, reason):
print reason
我看了一下日誌,因爲我對所發生的事情,一般興趣......(有些是我自己的聲明,一些是默認的)
014-10-16 13:42:58-0500 [SSHChannel session (0) on SSHService ssh-connection on ClientCommandTransport,client] closed last TCP connection
2014-10-16 13:42:58-0500 [ClientCommandTransport,client] service stopped
2014-10-16 13:42:58-0500 [ClientCommandTransport,client] connection lost
2014-10-16 13:42:58-0500 [ClientCommandTransport,client] [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionLost'>: Connection to the other side was lost in a non-clean fashion: Connection lost.
2014-10-16 13:42:58-0500 [ClientCommandTransport,client] ]
2014-10-16 13:42:58-0500 [ClientCommandTransport,client] connection lost
2014-10-16 13:42:58-0500 [ClientCommandTransport,client] [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionLost'>: Connection to the other side was lost in a non-clean fashion: Connection lost.
2014-10-16 13:42:58-0500 [ClientCommandTransport,client] ]
2014-10-16 13:42:58-0500 [ClientCommandTransport,client] Stopping factory <__main__.ClientCommandFactory instance at 0x02323030>
2014-10-16 13:42:58-0500 [-] Main loop terminated.
所以......它說連接失去了不潔淨的方式。有沒有更好的辦法,我應該阻止事情..?
我在一個星期前寫了這個問題...決定放棄paramiko。剛剛意識到我需要使用相同的連接運行多個命令(並且'&&'連接不夠)。我仍然不知道該怎麼做。最後,我想根據命令的響應來處理斷開連接,但沒有任何問題。 – 2014-10-15 15:48:19
您是否檢查[this](http://stackoverflow.com/questions/13920962/what-is-the-correct-way-to-close-a-twisted-conch-ssh-connection?lq=1)? 這可能是因爲你必須自己實施一些事情來妥善地關閉連接。無論如何,這與工作完成後停止反應堆無關。 – koleS 2014-10-18 12:15:32
@ koleS - 謝謝,我沒有看到。我嘗試在下面有人給我的答案中應用這些東西,但是反應器偶爾停止得太快,因爲在第一個或第二個完成後沒有添加所有連接。到處都有這麼多事情發生,我不確定在哪裏或如何捕捉或管理事情。 – 2014-10-18 18:16:46