Using Twisted to run command on remote system
I'm trying to write a Client/Server using Twisted that wi开发者_Python百科ll allow the client to issue remote commands on the server and receive response data in real time. i.e. If I run $> ssh server someProg.sh
, I will see the results in 'real time', not all at once when the process finishes. Is this sort of thing possible in Twisted? Thanks.
Absolutely. As already noted in a comment, you can do this by connecting to the SSH server directly with Twisted's "conch" library. This is more scalable (you can open lots of connections without any extra processes) and more portable (it can work on Windows) but it won't take into account your OpenSSH configuration, and you have to write a bunch of additional code to deal with things like host key verification. The other question doesn't directly address your main question here, either, which is about the output being processed as it arrives.
The simple answer is "yes", but here's a demonstration program that spawns several subprocesses and displays their output as it goes. You can replace the sys.executable
with another program to spawn (i.e. ssh
) and it'll work exactly the same way.
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()
You could use 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
精彩评论