我有我写的这个类:
class Remote(object):
def __init__(self, address, username, password):
self.address = address
self.username = username
self.password = password
def stdout(self, s):
print('out: ' + s)
def stderr(self, s):
print('err: ' + s)
def sh(self, s):
from paramiko import AutoAddPolicy, SSHClient
from threading import Thread
from time import sleep
ssh = SSHClient()
ssh.set_missing_host_key_policy(AutoAddPolicy())
ssh.connect(self.address, username = self.username, password = self.password)
stdin, stdout, stderr = ssh.exec_command(s)
def monitor(channel, method):
while True:
for line in channel.readlines():
method(line)
sleep(1)
Thread(target = monitor, args = (stdout, self.stdout)).start()
Thread(target = monitor, args = (stderr, self.stderr)).start()
然后我试着像这样运行它:
>>> from remote import Remote
>>> address = <removed>
>>> username = 'root'
>>> password = <removed>
>>> r = Remote(address, username, password)
>>> r.sh('echo Hello')
我没有得到任何输出。如果我改变周围的监控方法,而不是:
for line in channel.readlines():
method(line)
我只有 method(channel.read())
或 method(channel.readline())
,但在那种情况下,我只看到:
out:
err:
每秒一次 - 它实际上从未给我预期的结果:
out: Hello
我知道我的地址、用户名和密码都是正确的,因为我可以将它们输入 fabric
就好了。
>>> from fabric.api import env
>>> from fabirc.operations import sudo
>>> env.host_string, env.user, env.password = address, username, password
>>> sudo('echo Hello')
[<omitted>]: Hello
我在基于 paramiko
的类中做错了什么,fabric
显然能够处理?
编辑
我希望该方法是异步的。它应该立即返回。例如,如果我这样做:
r1 = Remote(<one set of credentials removed>)
r2 = Remote(<another set of credentials removed>)
r1.sh('echo Hello; sleep 5; echo World')
r2.sh('echo Hello; sleep 5; echo World')
那么结果应该是:
out: Hello
out: Hello
out: World
out: World
表明这两个调用是并行运行的,而不是:
out: Hello
out: World
out: Hello
out: World
这表明这两个调用是同步运行的。
最佳答案
问题是 monitor
中的 while True
循环阻止线程结束。保留第一部分不变并将最后几行更改为:
def monitor(channel, method):
while True:
l = channel.readline()
if l:
method(l)
else:
break
tout = Thread(target = monitor, args = (stdout, self.stdout))
terr = Thread(target = monitor, args = (stderr, self.stderr))
tout.start()
terr.start()
tout.join()
terr.join()
ssh.close()
将逐行打印给定命令行的输出,同时有一些东西要返回。
关于python - Paramiko 的 Read 方法都不适合我?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36780291/