У меня есть этот класс я написал:Ни один из методов чтения 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
Что указывает на то, что два вызова выполнялись синхронно.
Я хочу, чтобы методы выполнялись асинхронно. Он не должен ждать, пока команда не вернется. Если пользователь класса заботится о том, что команда выводит, они должны подклассы и использовать методы 'stdout' или' stderr'. – ArtOfWarfare
@ArtOfWarfare Понял, см. Правки – fernandezcuesta
Я не думаю, что вы понимаете - это все равно приводит к синхронному звонку. Я добавил изменение в свой вопрос, чтобы объяснить. Сказав это, ваш код действительно выводит что-то, тогда как мой исходный код ничего не выводит, поэтому +1 для этого. Кроме того, я дам вам знать, что сделать этот синхронный процесс довольно простым. Все, что мне нужно было сделать, это изменить имя 'sh' на' _sh' (указать его личное) и создать новый 'sh', который только начинает поток и запускает' _sh', а затем возвращается без соединения. Не уверен, что это самое элегантное решение или нет, но оно работает. – ArtOfWarfare