Python 执行远程程序
我正在用Python重写一个旧的Windows应用程序,并让它在Linux上运行。最开始,新应用需要调用旧应用,这样才能确保使用旧应用的客户和使用新应用的客户得到一致的结果。
我有一台Linux电脑,旁边还有一台Windows电脑,我想让Linux上的一个进程执行Windows上的一个命令,并获取结果(要同步进行)。
我最开始的想法是在Windows上写一个网络服务,但这样就需要在Windows机器上运行一个网络服务器,除了旧应用之外还要多一个东西。
接着我想到使用Twisted.Conch,这样可以通过网络执行命令,而不需要额外运行一个网络服务器,但我猜测在Windows机器上运行ssh服务器也会有一些额外的负担。
除了网络服务或ssh,我还有哪些其他方法可以在不同的机器上启动一个同步进程,使用Python?或者说,网络服务或ssh是最好的选择吗?如果网络服务或ssh确实是最好的方案,Twisted是否是我应该考虑使用的工具?
5 个回答
另一个选择是paramiko。它是一个用Python写的库,可以实现SSH功能。我用它来远程执行命令和把文件传输到运行SSH服务器的Windows电脑上。不过,它在Windows上不能正确捕捉输出,因为Windows的命令行有些特殊的地方。你用基于twisted的解决方案时,可能也会遇到同样的问题。
你想要捕捉什么样的结果呢?
我最后选择了使用SSH和Twisted。在我的Windows电脑上,我设置了freeSSHd作为一个Windows服务。在尝试让paramiko工作的时候,我遇到了很多问题,特别是关于我的公钥和私钥的设置,所以我决定试试Twisted,结果只花了几分钟就搞定了。因此,我根据Twisted的文档写了/借用了这个代码,以实现我在Linux上需要的SSH客户端功能。
from twisted.conch.ssh import transport
from twisted.internet import defer
from twisted.conch.ssh import keys, userauth
from twisted.conch.ssh import connection
from twisted.conch.ssh import channel, common
from twisted.internet import protocol, reactor
class ClientTransport(transport.SSHClientTransport):
def verifyHostKey(self, pubKey, fingerprint):
return defer.succeed(1)
def connectionSecure(self):
self.requestService(ClientUserAuth('USERHERE', ClientConnection()))
class ClientUserAuth(userauth.SSHUserAuthClient):
def getPassword(self, prompt=None):
return
def getPublicKey(self):
return keys.Key.fromString(data=publicKey)
def getPrivateKey(self):
return defer.succeed(keys.Key.fromString(data=privateKey))
class ClientConnection(connection.SSHConnection):
def serviceStarted(self):
self.openChannel(CatChannel(conn=self))
class CatChannel(channel.SSHChannel):
name = 'session'
def channelOpen(self, data):
data = 'abcdefghijklmnopqrstuvwxyz' * 300
self.return_data = ''
self.conn.sendRequest(self, 'exec', common.NS('C:\helloworld %-10000s' % data), wantReply=True)
def dataReceived(self, data):
self.return_data += data
def closed(self):
print "got %d bytes of data back from Windows" % len(self.return_data)
print self.return_data
self.loseConnection()
reactor.stop()
if __name__ == "__main__":
factory = protocol.ClientFactory()
factory.protocol = ClientTransport
reactor.connectTCP('123.123.123.123', 22, factory)
reactor.run()
这个方法运行得非常好!