IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Terminal + ssh + commande


Sujet :

Python

  1. #1
    Membre du Club
    Homme Profil pro
    Inscrit en
    Octobre 2006
    Messages
    107
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Octobre 2006
    Messages : 107
    Points : 64
    Points
    64
    Par défaut Terminal + ssh + commande
    Bonjour,
    Je suis entrain de mettre en place une petite application python + tkinter pour le contrôle de services et autres sur des serveurs distant.
    Envoyer une commande via paramiko ok pas de pb, mon problème réside dans le souhait de vouloir ouvrir suite à un appui bouton, un terminal et executer une connection et une commande de lecture de log sur ce terminal ouvert.
    Ou dans une autre solution serait de creer une fenêtre avec label avec import du log en lecture et rafrachissement du log.

    J ai essayé avec la bibliotheque OS ce qui me permet d ouvrir le terminal mais je bloque pour la syntaxe. Car lorsque je fais l'essai le terminal se lance et ma connexion ssh se faire sur le terminal de lancement du script.

    Si quelqu un peu m eclairer sur la méthodologie à aborder ou solution envisageable cela m aiderai.

    Vous remerciant.

  2. #2
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 201
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nièvre (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2013
    Messages : 2 201
    Points : 4 665
    Points
    4 665
    Par défaut
    Bonjour
    Citation Envoyé par Hybride76 Voir le message
    se lance et ma connexion ssh se faire sur le terminal de lancement du script.
    on ne comprend pas le problème et en plus tu ne donnes même pas ta commande au terminal

    Sinon, puisque tu dis que tu fais bien une connexion avec paramiko, il te suffit de lire "output" et de l'afficher dans ta gui
    pseudo code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def on_btn_clic():
      #client = SSHClient()
      #client.connect(...)
      stdin, stdout, stderr = client.exec_command('/usr/bin/cat /var/log/truc.log')
      mazone_texte.set(stdout.read.decode)
    A noter qui existe déjà quelques sujet sur ssh (et tkinter) dans ce forum.
    $moi= ( !== ) ? : ;

  3. #3
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 721
    Points : 31 044
    Points
    31 044
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par Hybride76 Voir le message
    mon problème réside dans le souhait de vouloir ouvrir suite à un appui bouton, un terminal et executer une connection et une commande de lecture de log sur ce terminal ouvert.
    Pas vraiment besoin d'un terminal. On peut appeler des programmes directement depuis Python.
    Un petit ersatz: for l in subprocess.run(("ssh", "localhost", "cat", "/etc/passwd"), stdout=subprocess.PIPE, encoding="utf-8").stdout.split("\n"): print(l).
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 894
    Points : 7 250
    Points
    7 250
    Par défaut
    Hello,

    Citation Envoyé par Sve@r
    Pourquoi pas directement un subprocess() qui va appeler ssh host "cat log" ???
    Peut-être que c'est suffisant pour son besoin, seul le PO pourra y répondre, mais je vois au moins une raison dans le cas où on l'utilise pour des tâches répétitives notamment en raison du coût d'initialisation de chaque nouvelle connexion SSH.
    En utilisant Paramiko, on peut réutiliser les connexions existantes et ainsi améliorer les performances de l'application.
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  5. #5
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 721
    Points : 31 044
    Points
    31 044
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    En utilisant Paramiko, on peut réutiliser les connexions existantes et ainsi améliorer les performances de l'application.
    En fait je ne conaissais pas paramiko et suis allé voir ce que c'est. Effectivement c'est plus adapté à ssh que subprocess(). Mais ma suggestion subprocess() était là que par rapport à sa demande de terminal, pour monter qu'on peut bosser sans lui.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  6. #6
    Membre du Club
    Homme Profil pro
    Inscrit en
    Octobre 2006
    Messages
    107
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Octobre 2006
    Messages : 107
    Points : 64
    Points
    64
    Par défaut Suite
    Bonjour,
    Merci pour vos réponses.

    Le 1er message a été réaliser via mon smartphone, ce qui explique l'absence de code ( je m'en excuse , car effectivement cela n'aide pas).

    Alors au niveau ssh je n’utilise pas paramiko comme explicité ,cela fut ma 1er intention mais je passe via subprocess plus simple pour ce que je voulais faire.

    L'objectif final est de pouvoir avoir un terminal connecté en ssh avec la lecture du log en question.

    Ou avoir le retour du log que je pourrias afficher dans un label tkinter, mais là il faut gérer le rafraîchissement.

    Je continue mes recherche pour arriver à coder cela. Merci pour votre aide et vos propositions.

    Voici le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    import os
     
    def com(id_cmd, HOST):
            id_cmd_station = list(services.keys())[id_cmd]
            print(services[id_cmd_station])
            send_cmd = services[id_cmd_station]
            print(HOST)
     
     
     
         # Define the SSH command to connect to the remote server
            ssh_command = "ssh root@" + HOST
     
            # List of commands you want to execute on the remote server
            remote_commands = [
            #send_cmd,
            os.system('gnome-terminal; tail -f /var/log/fichier.log')
            ]
     
            # Join the remote commands into a single string
            remote_commands_str = ";".join(remote_commands)
     
            # Combine the SSH command and the remote commands
            full_command = f"{ssh_command} '{remote_commands_str}'"
     
            # Execute the combined command
            result = subprocess.run(full_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
     
            # Check the result
            if result.returncode == 0:
                    print("Command executed successfully.")
                    print("Output:")
                    print(result.stdout)
            else:
                    print("Error executing the command:")
                    print(result.stderr)

  7. #7
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 201
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nièvre (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2013
    Messages : 2 201
    Points : 4 665
    Points
    4 665
    Par défaut
    Mais pourquoi avoir python pour ouvrir un terminal, autant lancer la commande ssh directement depuis le terminal (via un script bash voir python)?

    Citation Envoyé par Hybride76 Voir le message
    afficher dans un label tkinter, mais là il faut gérer le rafraîchissement.
    Ce n'est pas forcément compliqué ! Il faut juste faire un hook sur la sortie de la commande (pas compatible paramiko...). On doit pouvoir trouver beaucoup d'exemple sur le web. En gros :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    self.text = tk.Text(root, height=26, width=152)
    ...
    self.proc = Popen(MA_CMD, stdout=PIPE, stderr=STDOUT, text=True, shell=True,)
    # on attache read_output() aux modifs dans la sortie
    root.createfilehandler(self.proc.stdout, tk.READABLE, self.read_output)  # root = Tk()
     
    def read_output(self, pipe, mask):
      data = os.read(pipe.fileno(), 9999999).decode()
      self.text.insert(tk.END, data)
    $moi= ( !== ) ? : ;

  8. #8
    Membre du Club
    Homme Profil pro
    Inscrit en
    Octobre 2006
    Messages
    107
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Octobre 2006
    Messages : 107
    Points : 64
    Points
    64
    Par défaut suite
    Citation Envoyé par papajoker Voir le message
    Mais pourquoi avoir python pour ouvrir un terminal, autant lancer la commande ssh directement depuis le terminal (via un script bash voir python)?
    Merci pour ton retour.

    Le but étant de pouvoir ouvrir une liaison en auto pour aider des personnes non habituées aux commandes ssh.

    Au plus simple c'est réussir avoir un terminal + lancer un commande ssh et enfin un tail -f var un log, le tout via un push d'un bouton.

    Il faut que cela soit usuel tout simplement.

    Merci.

  9. #9
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 201
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nièvre (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2013
    Messages : 2 201
    Points : 4 665
    Points
    4 665
    Par défaut
    J'ai bien compris et ce n'était pas ma réponse.
    Simplement, tu peux tout faire dans tk, je t'ai donné le code, le rafraichissement en lui-même, c'est 2 lignes de python. C'est "compliqué" de de créer une interface graphique python avec pour seul but d'avoir un bouton qui va lancer un terminal
    - possible de faire un alias "log", alors il est pas trop compliqué de lancer cette commande pour pas mal d'utilisateurs
    - possible de créer de(s) lanceur(s). ici, le bouton est remplacé par une entrée dans le menu de l'os



    Un petit exemple très basique tout tk avec subprocess. Que ce soit avec ssh ou non, cela ne change strictement rien, c'est un code classique non bloquant en gui.
    Je n'ai même pas le double de lignes que ton code qui lance un terminal

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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()
    $moi= ( !== ) ? : ;

  10. #10
    Membre du Club
    Homme Profil pro
    Inscrit en
    Octobre 2006
    Messages
    107
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Octobre 2006
    Messages : 107
    Points : 64
    Points
    64
    Par défaut Suite / Fin
    Après quelques modifs selon mes besoins cela fonctionne.

    Merci pour ton aide, c'est là que je vois que j'ai encore pas mal à apprendre.

    Encore merci.

  11. #11
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 201
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nièvre (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2013
    Messages : 2 201
    Points : 4 665
    Points
    4 665
    Par défaut
    Petit complément pour ceux qui font une recherche sur ce forum avant de demander.

    Si on utilise plutôt une clé avec pass phrase, on peut demander cette passphrase en graphique.
    Il faut indiquer quelle application graphique existe pour notre système, par exemple avec kde c'est "ksshaskpass" (paquets du genre ****-askpass)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    subprocess.run(
        "/usr/bin/ssh-add ~/.ssh/id_rsa", 
        shell=True,    # si on passe une clé
        env=dict(os.environ) | {
            "SSH_ASKPASS": "/usr/bin/ksshaskpass",
            "SSH_ASKPASS_REQUIRE": "prefer",
        },
    )
    Ensuite, on peut appeler notre commande ssh qui ne demandera plus la passphrase

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ssh -i '/home/moi/.ssh/id_rsa' ...

    Il est possible de se passer de ssh-add, et de mettre cet environnement dans l'appel à ssh (mais a chaque appel, nous avons une demande)
    $moi= ( !== ) ? : ;

Discussions similaires

  1. SSH Paramiko - How to execute a ssh command on a server
    Par shakenfr dans le forum Bibliothèques tierces
    Réponses: 2
    Dernier message: 06/01/2017, 01h33
  2. [PHP 5.5] ouverture terminal ssh depuis php
    Par patgmh dans le forum Langage
    Réponses: 3
    Dernier message: 14/12/2016, 12h01
  3. ssh "commande" et chroot
    Par Neckara dans le forum Administration système
    Réponses: 7
    Dernier message: 08/10/2013, 14h31
  4. [SSH2] PHP/SSH commande SQL
    Par Jonathan.b dans le forum Bibliothèques et frameworks
    Réponses: 1
    Dernier message: 25/10/2007, 08h24
  5. Ssh commande not found
    Par marielaure2805 dans le forum Réseau
    Réponses: 3
    Dernier message: 19/10/2006, 12h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo