2010-07-13 185 views
4

我正在使用Python重新编写一个传统的Windows应用程序,并在Linux上运行。最初,新应用程序需要调用旧应用程序,以便仍然使用旧应用程序的客户和使用新应用程序的客户之间获得一致的结果。python执行远程程序

所以我有一个Linux盒子,坐在Windows盒子旁边,我想要一个Linux框上的进程在Windows盒子上执行一个命令并捕获结果(同步)。

我最初的想法是在Windows机器上编写Web服务,但这意味着除了遗留应用程序之外,还要在Windows机器上运行Web服务器。

因此,后来我认为使用Twisted.Conch可能允许我在网络上执行一个命令,而无需运行Web服务器的额外开销,但我认为还有一个开销,在运行ssh服务器Windows机器。

除了Web服务或SSH之外,我还可以使用Python在不同的机器上启动同步过程,或者是Web服务或ssh最佳方法的一些替代方法?另外,如果Web服务或ssh是追求的最佳路线,那么我应该考虑使用Twisted吗?

+2

同步 - 意思是“实时”,我希望Linux上的执行暂停并等待Windows响应。与在异步情况下我将某些工作单元提交给Windows的情况相反,然后继续在Linux上执行其他操作,并在Windows完成时收到通知。 – 2010-07-13 15:24:10

回答

5

我结束了与SSH +扭曲。在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() 

这一直工作的很棒!

1

尝试QAMRabbitMQ

+1

谢谢,我会看看 - 如果我最终将其用于其他提交的答案,我会接受这个答案。 – 2010-07-13 13:46:54

0

我经常使用一个叫做winexe的小程序,它基于Samba。

以下是command syntax的外观,以下是一些installation options

+0

这可能会起作用 - 由于缺少能够找到的文档,我有点关闭。 – 2010-07-13 15:35:45

+0

可以理解。似乎还没有包含在安装中的manpage,但至少'winexe --help'提供了所有命令选项的完整列表。 – ewall 2010-07-13 20:22:26

4

另一种选择是paramiko。这是一个实现SSH的Python库。我用它来远程执行命令并将文件传输到运行SSH服务器的窗口框。问题是由于windows命令外壳的特殊性,它无法正确捕获窗口上的stdout。您可能会遇到与基于扭曲的解决方案相同的问题。

你试图捕获什么样的结果?

+0

我不完全确定结果会是什么样子,在这一点上,我假设我需要从stdout中获得它们。 – 2010-07-13 16:01:51

+0

我接受这个答案,不是因为它必然是“正确的”我不认为这个问题真的有对或错的答案,但我要去SSH路线,最有可能使用Paramiko。 – 2010-07-19 16:12:16

1

RPC是IMO的正确答案。

我想:

  • 使用SimpleXMLRPCServer为Windows机器
  • 使用的xmlrpclib在Linux计算机

标准库中将会给你最自由。你可以实现你所需要的,而且你不必担心windows API,DCOM等夸大技术,甚至在Windows机器上,你都在Python领域。

旁注: 扭曲当然总是一个很好的选择,所以不要担心;我认为苹果CalDav服务器也在Twisted上运行。