Использование Twisted для запуска команды на удаленной системе - PullRequest
2 голосов
/ 06 августа 2011

Я пытаюсь написать клиент / сервер, используя Twisted, что позволит клиенту выполнять удаленные команды на сервере и получать данные ответов в режиме реального времени. то есть, если я выполню $> ssh server someProg.sh, я увижу результаты в режиме реального времени, а не сразу, когда процесс завершится. Это возможно в Twisted? Благодаря.

Ответы [ 2 ]

4 голосов
/ 06 августа 2011

Абсолютно.Как уже отмечалось в комментарии, вы можете сделать это, подключившись к SSH-серверу напрямую с помощью библиотеки Twisted "conch" .Это более масштабируемый (вы можете открыть много соединений без каких-либо дополнительных процессов) и более переносимый (он может работать в 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()
0 голосов
/ 08 августа 2011

Вы можете использовать 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 
...