Ich habe diese Klasse die ich geschrieben habe:Keine von Paramikos Read-Methoden funktionieren für mich?
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()
Dann habe ich es so versuchen laufen:
>>> from remote import Remote
>>> address = <removed>
>>> username = 'root'
>>> password = <removed>
>>> r = Remote(address, username, password)
>>> r.sh('echo Hello')
Und ich bekomme keine Ausgabe. Wenn ich den Monitor Methode ändern, um so statt:
for line in channel.readlines():
method(line)
habe ich einfach method(channel.read())
oder method(channel.readline())
, aber in diesem Fall, ich sehe gerade:
out:
err:
einmal pro Sekunde - es nie wirklich gibt mir die erwarteten Ergebnisse:
out: Hello
ich weiß, dass meine Adresse, Benutzername und Passwort ist alles in Ordnung, weil ich sie in fabric
ganz gut ernähren kann.
>>> 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
Was bin ich in meiner paramiko
basierten Klasse falsch zu machen, die fabric
offenbar der Lage ist, zu behandeln?
bearbeiten
möchte ich die Methode von asynchron. Es sollte sofort zurückkehren. Zum Beispiel, wenn ich dies tun:
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')
Dann sollten die Ergebnisse sein:
out: Hello
out: Hello
out: World
out: World
anzeigt, dass die zwei Anrufe parallel liefen, nicht:
out: Hello
out: World
out: Hello
out: World
die darauf hindeuten würde, dass Die beiden Anrufe liefen synchron.
Ich möchte die Methoden asynchron ausführen lassen. Es sollte nicht warten, bis der Befehl beendet ist. Wenn sich der Benutzer der Klasse darum kümmert, was der Befehl ausgibt, sollte er die Methoden 'stdout' oder' stderr' ableiten und verwenden. – ArtOfWarfare
@ArtOfWarfare Verstanden, siehe Bearbeitungen – fernandezcuesta
Ich glaube nicht, dass Sie verstehen - das führt immer noch dazu, dass die Anrufe synchron sind. Ich habe eine Änderung zu meiner Frage hinzugefügt, um sie zu erklären. Allerdings gibt Ihr Code tatsächlich etwas aus, während mein ursprünglicher Code nichts ausgibt, also +1 dafür. Außerdem werde ich Sie wissen lassen, dass das Synchronisieren eigentlich ziemlich einfach war. Ich musste nur den Namen von 'sh' in' _sh' ändern (um anzuzeigen, dass es privat ist) und ein neues 'sh' machen, das nur einen Thread startet und' _sh' darauf ausführt, dann ohne Verbindung zurückkehrt. Nicht sicher, ob das die eleganteste Lösung ist oder nicht, aber es scheint zu funktionieren. – ArtOfWarfare