Paramiko und exec_command - töten remote-Prozess?
Ich bin mit Paramiko zu tail -f
eine Datei auf einem remote-server.
Zuvor waren wir laufen über ssh -t
, aber das erwies sich als unzuverlässig, und die -t
verursacht Probleme mit unserer remote-scheduling-system.
Meine Frage ist, wie man tötet Schwanz, wenn das Skript fängt ein SIGINT?
Mein Skript (basierend auf Lang laufende ssh-Kommandos in python-paramiko-Modul (und wie Sie zu beenden))
#!/usr/bin/env python2
import paramiko
import select
client = paramiko.SSHClient()
client.load_system_host_keys()
client.connect('someserver', username='victorhooi', password='blahblah')
transport = client.get_transport()
channel = transport.open_session()
channel.exec_command("tail -f /home/victorhooi/macbeth.txt")
while True:
try:
rl, wl, xl = select.select([channel],[],[],0.0)
if len(rl) > 0:
# Must be stdout
print channel.recv(1024)
except KeyboardInterrupt:
print("Caught control-C")
client.close()
channel.close()
exit(0)
Das Skript fängt meine Strg-C erfolgreich, und enden. Allerdings, es lässt die tail -f
Prozess läuft auf dem remote-system.
Weder client.close () - noch-Kanal.close () - scheinen Sie, es zu beenden.
Welchen Befehl kann ich das Problem in den except-block um es zu töten?
Remote-server mit Solaris 10.
InformationsquelleAutor victorhooi | 2011-10-12
Du musst angemeldet sein, um einen Kommentar abzugeben.
Während nicht die effizienteste Methode, dies sollte funktionieren. Nachdem Sie STRG+C; In die KeyboardInterrupt-handler könnten Sie
exec_command("killall -u %s tail" % uname)
etwa so:Dies würde die töten, die offenen Prozesse mit dem Namen
tail
. Das kann Probleme verursachen, wenn Sietail
s open, die Sie nicht wollen, um zu schließen, wenn das ist der Fall, Sie könntengrep
eineps
haben, erhalten die pid und diekill -9
.Zuerst Schwanz gelesen
n
Zeilen am Ende der Datei, bevor Sie die folgenden. setn
zu einem einzigartigen nuber wietime.time()
, da die Rute keine Sorge, wenn diese Zahl größer ist dann die Anzahl der Zeilen in der Datei, die die große Anzahl vontime.time()
sollte nicht zu Problemen führen und wird einzigartig sein. Dann ist grep für diese eindeutige Nummer imps
:Siehe meine edits oben, die Formatierung ist alles komisch in diesem Kommentar ).
Yup, dass die Lösung funktioniert. Als Sie jedoch bemerken, es ist ein bisschen hacky (der ganze grepping für PIDs, besonders, wenn mehrere Leute Schwanz die gleiche Datei). Noch funktioniert es. Ich bin überrascht, dass es nicht möglich ist, ziehen Sie die PID über Paramiko, wie Sie normalerweise mit Python POpen. Seltsam.
Diese Lösung ist nicht ein pythonic Lösung.. Sie sollten nie haben, um zu laichen einen Prozess auf dem remote-Rechner, zu töten den Befehl, den Sie schon gelaicht... Was ist, wenn dieser Befehl getötet werden muss? Was wäre, wenn du einen ssh server laufen auf einer Maschine, die nicht den kill-Befehl?
InformationsquelleAutor chown
Sollten Sie die Verwendung von ssh-keepalives... das problem, das Sie haben, ist, dass die remote-shell keine Möglichkeit hat, zu wissen (standardmäßig), dass Sie Ihre ssh-Sitzung getötet wurde. Keepalives aktivieren Sie die remote-shell zu erkennen, dass Sie getötet die Sitzung
Festlegen der keepalive-Wert so niedrig, wie Sie möchten (sogar 1 Sekunde)... nach einigen Sekunden, die remote shell werden sehen, dass der ssh-login ist gestorben, und es wird beendet alle Prozesse, die gespawnt wurden.
Sie müssen warten, für die mehrere Abständen keepalive - ... setzen Ihr keepalive auf 1, und ich bin mir ziemlich sicher, du wirst es sehen, kündigen Sie innerhalb von 10 Sekunden (wenn Solaris verhält sich wie meine BSD-Boxen)
Sie sollten, Bearbeiten Sie die Frage mit allen relevanten details wie die.
Sie kann es macht die Dinge einfacher für Sie, wenn Sie explizit aufrufen einer shell mit
channel.invoke_shell()
... obwohl dies erfordert mehr änderungen an Ihrem SkriptInformationsquelleAutor Mike Pennington
Gibt es eine Möglichkeit, dies zu tun. Es funktioniert wie auf der shell
Die option-t ist die Eröffnung eines pseudo-pty-Hilfe ssh zu verfolgen, wie lange dieser Prozess dauern soll. das gleiche kann getan werden, über pormiko über
vor execute_command(...). Dies wird nicht öffnen Sie eine shell, wie es mit dem Kanal.invoke_shell(), es fordert eine pseudo-interface zu binden, alle Prozesse zu. Der Effekt kann auch gesehen werden, wenn ps-aux ausgegeben wird auf dem remote-Computer, der Prozess ist jetzt an der sshd mit einem ptxXY-Schnittstelle.
InformationsquelleAutor Sven
Ich einfach auf dieses Problem und war nicht in der Lage zur Ausgabe eines pkill um den Prozess zu beenden am Ende.
Eine bessere Lösung ist das ändern der Befehl ausgeführt werden:
So können Sie Ihre tail-Befehl so lange, wie Sie benötigen. Sobald Sie senden ein newline, um die remote-Prozess, der kill %1 ausgeführt wird, und stoppen Sie den tail-Befehl, den Sie im hintergrund. (Referenz: %1 ist eine jobspec und verwendet, um zu beschreiben, der erste Prozess wurde im hintergrund in Ihrer Sitzung, d.h. der tail-Befehl)
InformationsquelleAutor ibfrog
Hier ist ein Weg, um die remote-Prozess-ID:
Und hier ist, wie es zu verwenden (ersetzen
...
mit den bits in der ursprünglichen Frage):Gleiche Sache. 🙂 Die Verwendung von
exec
bedeutet, dass der Befehl ausgeführt wird, erbt die shell-PID.InformationsquelleAutor Søren Løvborg
Speziell für 'Schwanz', Sie könnten die Verwendung der --pid=PID-argument und lassen Schwanz kümmern:
InformationsquelleAutor c-urchin
Können Sie get_pty wie beschrieben in https://stackoverflow.com/a/38883662/565212.
E. g. Szenario - Wann rufen Sie client/Kanal.close():
Schritt 1: Führen Sie einen remote-Befehl, schreibt in die log-Datei.
Schritt 2: erzeugen Sie einen thread, der führt den tail-Befehl und die Blöcke in die readline loop
Schritt 3: In der main-thread, wenn der Befehl zurückgibt, wissen Sie, es werden keine Protokolle mehr, töten den Schwanz.
InformationsquelleAutor Tapomay
Hatte das gleiche problem mit
ssh -t
. Es gibt eine Bibliothek namens näher - es läuft einem remote-Prozess über ssh und schließt automatisch für Sie. Überprüfen Sie es heraus.InformationsquelleAutor Yoav Kleinberger