2011-08-06 70 views
2

我正在尝试编写一个使用Twisted的客户端/服务器,它将允许客户端在服务器上发出远程命令并实时接收响应数据。即如果我运行$> ssh server someProg.sh,我将在“实时”看到结果,而不是在过程结束时立即看到结果。 Twisted中有这种可能吗?谢谢。使用Twisted在远程系统上运行命令

+3

这似乎是http://stackoverflow.com/questions/4617507/best-way-to-run-remote-commands完全相同的副本-thru-ssh-in-twisted –

回答

4

绝对。正如评论中已经指出的那样,您可以通过connecting to the SSH server directly with Twisted's "conch" library来完成此操作。这是更具扩展性的(你可以在没有任何额外进程的情况下打开大量连接),并且更加便携(它可以在Windows上工作),但它不会考虑你的OpenSSH配置,你必须编写一堆额外的代码来处理像主机密钥验证一样。另一个问题并没有直接解决你的主要问题,也就是说,它是关于正在处理的输出。

简单的答案是“是”,但这里有一个演示程序,它生成几个子进程并随着显示它们的输出。您可以用sys.executable替代另一个产卵程序(即ssh),它将以完全相同的方式工作。

import os, sys 

from twisted.internet.protocol import ProcessProtocol 
from twisted.internet import reactor 
from twisted.internet.defer import Deferred, gatherResults 

script = """ 
import time 
for x in range(3): 
    time.sleep(1) 
    print(x) 
""" 

class SimpleProcess(ProcessProtocol): 
    def __init__(self, id, d): 
     self.id = id 
     self.d = d 
    def outReceived(self, out): 
     print('Received output: {out} from: {proc}' 
       .format(out=repr(out), proc=self.id)) 
    def processEnded(self, reason): 
     self.d.callback(None) 

ds = [] 
for x in range(3): 
    d = Deferred() 
    reactor.callLater(
     x * 0.5, reactor.spawnProcess, SimpleProcess(x, d), 
     sys.executable, [sys.executable, '-u', '-c', script], 
     os.environ) 
    ds.append(d) 

gatherResults(ds).addBoth(lambda ignored: reactor.stop()) 

reactor.run() 
+1

感谢您的回复。我现在意识到,我的问题似乎意味着我特别想使用SSH,但我实际上试图避免它。当我说我正在写客户端/服务器时,我的意思是我需要控制两端;我还宁愿在没有认证的情况下运行,这需要SSH。 – Doug

+0

在这种情况下,你会想在你的服务器中执行'spawnProcess',响应某些协议消息(即从dataReceived下的某个地方),而不是在这个例子中显示的callLater。但请随时用类似的标签问一个更具体的问题:-)。 – Glyph

+0

谢谢;无缓冲标志(-u)实际上使我获得了我想要的行为。 – Doug

-1

你可以使用的paramiko LIB http://www.lag.net/paramiko/

import paramiko 

class XXX(): 

def ssh_processing(self, params): 

     ssh = paramiko.SSHClient() 
     ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 

     ssh_connection = ssh.connect(ip, username=params['username'] , password=params['password']) 

     result = self.exec_ssh(ssh, cmd) 

def exec_ssh(self, ssh, cmd): 
    self._log('Exec [%s]' % cmd) 
    (stdin, stdout, stderr) = ssh.exec_command(cmd) 
    data = { 
      'stdin' : '', #self._read_all(stdin), 
      'stdout' : self._read_all(stdout), 
      'stderr' : self._read_all(stderr) 
     } 
    if len(data['stderr']): 
     msg = 'SSH Error: [%s]' % data['stderr'] 
     self._error(msg) 

    if 'command not found' in data['stderr']: 
     raise Exception(msg) 

    return data 
+1

问题是关于如何使用Twisted,所以这并没有真正回答它。 – Glyph

相关问题