1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| #!/usr/bin/env python
import os
from subprocess import Popen, PIPE, STDOUT
import tkinter as tk
from tkinter import simpledialog, scrolledtext
TEMPLATE = "sshpass -p '{0}' ssh 'ssh://moi@{1}:22' {2}"
'''
ssh -i {fichier_clé} 'ssh://{$user}@{server}:{port}' {command}
'''
CMDS = {
"ping" : ["ping developpez.com", "127.0.0.1", ""],
"journald" : ["/usr/bin/journalctl -f --no-pager","127.0.0.1", ""],
}
class Application:
def __init__(self, root):
self.root = root
self.text = scrolledtext.ScrolledText(root, height = 26, width = 132)
self.text.pack()
self.proc = None # process ssh
for title, cmd in CMDS.items():
tk.Button(root, text=title, command=lambda name=title: self.start(name)).pack(side=tk.LEFT)
tk.Button(root, text="Stop", command=self.stop).pack(side=tk.RIGHT)
def hook_output(self, pipe, mask):
"""Lire sortie du process output, passer result au GUI"""
if not self.proc:
return
data = os.read(pipe.fileno(), 9999999).decode()
if not data:
self.root.deletefilehandler(self.proc.stdout)
self.root.after(1000, self.stop())
return
#eventuellement, on formate la sortie pour la vue...
self.text.insert(tk.END, data)
def start(self, title):
self.stop()
self.text.delete(1.0,tk.END)
cmd = CMDS.get(title)
if not cmd[-1]:
cmd[-1] = simpledialog.askstring("ssh", "Mot de passe", show='*')
self.proc = Popen(
TEMPLATE.format(cmd[-1], cmd[1], cmd[0]),
stdout=PIPE, stderr=STDOUT, text=True, shell=True,
)
# on attache hook_output() aux modifs de la sortie
self.root.createfilehandler(self.proc.stdout, tk.READABLE, self.hook_output)
def stop(self, quit=False):
"""Stop process et quitter GUI."""
if self.proc:
self.proc.terminate()
self.root.deletefilehandler(self.proc.stdout)
if self.proc.poll() is None: # process non terminé
self.proc.kill()
self.proc.stdout.close()
self.proc.wait()
self.proc = None
if quit:
self.root.destroy()
if __name__ == "__main__":
root = tk.Tk()
app = Application(root)
root.protocol("WM_DELETE_WINDOW", lambda : app.stop(True)) # ferme le subprocess
root.mainloop() |