使用Twisted在远程系统上运行命令
我正在尝试用Twisted写一个客户端/服务器程序,这样客户端就可以在服务器上发出远程命令,并实时接收响应数据。也就是说,如果我运行 $> ssh server someProg.sh
,我希望能看到实时的结果,而不是等到整个过程结束后才看到所有结果。请问在Twisted中可以做到这样的功能吗?谢谢。
2 个回答
-1
你可以使用 paramiko 这个库,详细信息可以查看这个链接: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
5
当然可以。正如评论中提到的,你可以通过直接用Twisted的“conch”库连接到SSH服务器来实现。这种方法更灵活(你可以打开很多连接而不需要额外的进程),而且更便携(可以在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()