Puis-je voir dans un fichier journal toutes les tâches basées sur l'interface graphique dans son autre format de ligne de commande?

9

Par exemple, j'ouvre normalement le tapis de souris (équivalent xfce de gedit) dans le menu des applications. Cependant, je sais que vous pouvez également le faire dans un terminal en tapant mousepad.

Suivant cet exemple, ce que je veux, c'est chaque fois que j'ouvre le tapis de souris via l'interface graphique, une nouvelle ligne est écrite dans un fichier journal indiquant quelque chose comme Sep 5 15:35:11 lucho@lucho:~$ mousepad. Plus généralement, ce que je veux, c'est consigner toutes les activités de l'interface graphique potentiellement réalisables via la ligne de commande (comme ouvrir des programmes, changer les autorisations, modifier les paramètres système, etc.) mais écrites dans son autre format d'exécution en ligne de commande . Je veux cela afin d'améliorer mes connaissances sur l'utilisation de la ligne de commande (sans passer par les manpages). Il y a beaucoup de choses que je fais via l'interface graphique que je ne fais pas via la ligne de commande (certaines potentiellement automatisables via un script ou via des raccourcis clavier) et avoir ce fichier journal serait un bon moyen de les apprendre.

Je suis conscient de l'existence du fichier syslog /var/logmais ce n'est pas ce dont j'ai besoin. Pour autant que je sache, l'application Activity Log Manager des référentiels Ubuntu n'affiche pas le format de ligne de commande. J'ai besoin de quelque chose comme le fichier .bash_history qui existe dans mon dossier d'accueil mais qui enregistre mes activités basées sur l'interface graphique.


la source
vous pouvez utiliser un outil comme strace pour jeter un coup d'œil dans un programme en cours d'exécution et voir comment le système l'appelle, cela générera cependant de grandes quantités de données
Amias
Si vous cherchez un programme qui enregistre simplement le nom binaire des programmes qui s'ouvrent dans l'interface graphique, je peux le faire dans un script. Si c'est ce que vous voulez, faites le moi savoir. Il serait préférable que vous clarifiiez vos besoins réels, veuillez donc modifier votre question. L'enregistrement d'activités basées sur une interface graphique, comme cliquer sur des boutons ou ouvrir un nouvel onglet dans un navigateur n'est pas quelque chose qui peut être facilement enregistré, car celles-ci ne sont pas connectées à des commandes shell réelles
Sergiy Kolodyazhnyy
@Serg Le journal que vous proposez serait certainement ce que je recherche. Quelque chose comme un journal "Task Manager" basé sur des noms CLI au lieu de noms GLI qui, comme le suggère la réponse existante, pourrait ne pas coïncider. Par exemple, si j'ouvre «Language Support» dans les paramètres, je veux connaître son équivalent CLI. Etc ...
@luchonacho OK, je vais commencer à écrire aujourd'hui, je posterai quand il sera prêt. Soit dit en passant, «Prise en charge linguistique» dans les paramètres n'a pas son propre équivalent cli. Certaines choses, comme le menu Bluetooth ou le menu d'arrière-plan, le font - vous pouvez spécifier unity-control-center backgroundou gnome-control-center background(selon votre bureau, Unity ou XFCE ou GNOME). Mais le monde extérieur ne verra probablement quegnome-control-center
Sergiy Kolodyazhnyy
Il existe de très nombreuses façons de savoir quelle tâche est effectuée par les applications GUI et de découvrir leur équivalent cli. Il me semble assez inefficace d'essayer d'enregistrer aveuglément tout ce qui se passe par la force brute, en étant sûr que vous n'attraperez pas tout. Mieux le découvrir dans des cas spécifiques, en utilisant des outils spécifiques.
Jacob Vlijm

Réponses:

2

introduction

Bien qu'il ne soit pas possible de consigner toutes les actions de l'interface graphique, des choses telles que les commandes de journalisation qui correspondent aux fenêtres ouvertes peuvent être effectuées. Voici le script python simple qui fait le travail. Il est toujours en développement, mais accomplit 90% de la tâche requise.

Code source

#!/usr/bin/env python3
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('Gdk', '3.0')
from gi.repository import Gdk,Gtk
import time
import os
import subprocess

def run_cmd(cmdlist):
    """ Reusable function for running external commands """
    new_env = dict(os.environ)
    new_env['LC_ALL'] = 'C'
    try:
        stdout = subprocess.check_output(cmdlist, env=new_env)
    except subprocess.CalledProcessError:
        pass
    else:
        if stdout:
            return stdout
def print_info(stack,event):
    base_xprop = ['xprop','-notype']
    for xid in stack:
        pid = None
        check_pid = run_cmd(base_xprop + [ '_NET_WM_PID', '-id',str(xid)])
        if check_pid:
            pid = check_pid.decode().split('=')[1].strip()
        with open('/proc/'+pid+'/cmdline') as fd:
            command = fd.read()
        print(time.strftime("%D %H:%M:%S" + " "*3) + event + pid + " " + command)

def main():
    sc = Gdk.Screen.get_default()
    old_stack = None

    while True:
        stack = [ win.get_xid() for win in sc.get_window_stack() ]
        if old_stack:
            # Difference between current and old stack will show new programs
            diff = set(stack) - set(old_stack)
            if diff:
                print_info(diff," 'New window open' ")
        else:
            print_info(stack," 'Script Started' ")

        old_stack = stack
        time.sleep(2)

if __name__ == '__main__': main()

Essai:

$ ./log_open_windows.py                                                                                                
01/25/17 15:33:13    'Script Started' 2915 nautilus-n
01/25/17 15:33:13    'Script Started' 3408 /opt/google/chrome/chrome
01/25/17 15:33:13    'Script Started' 12540 /usr/bin/python/usr/bin/x-terminal-emulator
01/25/17 15:33:13    'Script Started' 2454 compiz
01/25/17 15:33:13    'Script Started' 2454 compiz
01/25/17 15:33:13    'Script Started' 2454 compiz
01/25/17 15:33:13    'Script Started' 2454 compiz
01/25/17 15:33:13    'Script Started' 2454 compiz
01/25/17 15:33:21    'New window open' 15143 /usr/lib/firefox/firefox-new-window
01/25/17 15:33:27    'New window open' 15196 unity-control-center

Le script affiche l'horodatage, le type d'événement, le PID de la fenêtre et la commande correspondante.

Comment utiliser

Les règles standard de tout script s'appliquent. Assurez-vous de stocker le script dans le ~/binrépertoire. Si vous n'avez pas de ~/binrépertoire, créez-en un. Enregistrez-y le fichier de script et assurez-vous qu'il est exécutable avec chmod +x ~/bin/log_open_windows.py. Après cela, vous pouvez l'exécuter à partir de la ligne de commande à tout moment en appelant ~/log_open_windows.pyen ligne de commande.

Sergiy Kolodyazhnyy
la source
Merci. Cela semble prometteur! Deux questions. Comment l'exécuter? Quel est le 10% manquant?
Nifty! +1 de moi!
Fabby
@luchonacho J'ai ajouté un paragraphe sur l'utilisation. Je vous recommande de l'utiliser manuellement depuis la ligne de commande comme je l'ai décrit. Vous pouvez le faire démarrer automatiquement au démarrage, mais je ne recommande pas de le faire. Les 10% manquants sont d'autres fonctionnalités que je voulais ajouter, mais je ne pense pas que je vais les ajouter. Cela fonctionne assez bien pour l'instant. Mais peut-être que je changerai encore d'avis
Sergiy Kolodyazhnyy
C'est probablement le plus proche de ce que je cherchais, sachant que la solution parfaite n'existe pas. Merci!
4

Proposer ce type de fichier journal comme base d'apprentissage est en fait une excellente idée!

Malheureusement, de nombreuses actions des programmes GUI sont implémentées dans le programme lui-même, sans utiliser de commandes externes; Et même s'il utilise des commandes externes, cela peut être d'une manière différente de celle que l'on ferait dans un shell;
Cela n'existe donc pas et n'est pas facile à mettre en œuvre.

Mais j'ai une solution pour une partie du problème: le nom du programme dans l'interface graphique est parfois différent du nom du programme que l'on doit connaître pour une commande shell - pas seulement si le nom de l'interface graphique est traduit dans une langue locale.

Par exemple, comment démarrer le programme Filesdans la ligne de virgule?

Nous devons examiner tous les *.desktopfichiers pour le nom. Là, on retrouve la commande dans la Execligne:

locate -b '.desktop' | xargs grep -ls '^Name.*=Files$' | xargs grep '^Exec.*'

répertorie les noms de fichiers de bureau et les commandes pour le programme GUI File- remplacez-le par le nom exact que vous recherchez - même s'il s'agit de plusieurs mots (pour la recherche de sous-chaîne, omettez le =et $).

Avec la commande, je trouve Filespeut-être nautilus, dolphinou active-filebrowser:

/etc/xdg/autostart/nautilus-autostart.desktop:Exec=nautilus -n
/usr/share/app-install/desktop/nemo:nemo.desktop:Exec=nemo %U
/usr/share/app-install/desktop/plasma-active:kde4__active-filebrowser.desktop:Exec=active-filebrowser -graphicssystem raster %u
/usr/share/applications/nautilus-folder-handler.desktop:Exec=nautilus %U
/usr/share/applications/nautilus.desktop:Exec=nautilus --new-window %U
/usr/share/applications/nautilus.desktop:Exec=nautilus --new-window
Volker Siegel
la source
Mmm, ma question sous-tend une vue de Linux d'une complexité évolutive, où des programmes plus élaborés sont construits sur du code plus simple, donc je pensais que toute application GUI s'appuie sur des commandes de terminal mais pourrait ne pas être le cas puisque le terminal est basé sur du code bash alors que le logiciel pourrait être écrit en python ou c ++ ou etc. Je me trompe?
Les couches de complexité existent, mais d'une manière différente: grossièrement, il y a des appels système, des fonctions de bibliothèque, et en plus soit une interface utilisateur graphique, soit une interface de ligne de commande - ce sont des alternatives.
Volker Siegel