2011-08-06 71 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

相關問題