Ни один из методов чтения Paramiko не работает для меня?
У меня есть этот класс, который я написал:
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
Что означало бы, что два вызова выполнялись синхронно.
1 ответ
Проблема в том, что while True
зациклиться monitor
предотвращает поток до конца. Оставьте первую часть как есть и измените последние строки на:
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()
будет выводить вывод данной командной строки построчно, в то время как есть что-то, что должно быть возвращено.