¿Puedo ver en un archivo de registro todas las tareas basadas en GUI en su formato alternativo de línea de comandos?

9

Por ejemplo, normalmente abro el mousepad (equivalente xfce de gedit) desde el menú de aplicaciones. Sin embargo, sé que también puedes hacer esto en una terminal escribiendo mousepad.

Siguiendo este ejemplo, lo que quiero es que cada vez que abro el mousepad a través de la GUI, se escriba una nueva línea en un archivo de registro que indique algo así Sep 5 15:35:11 lucho@lucho:~$ mousepad. Más en general, lo que quiero es registrar todas las actividades de la GUI que son potencialmente posibles a través de la línea de comandos (como abrir programas, cambiar permisos, modificar una configuración del sistema, etc.) pero escritas en su formato alternativo de ejecución de línea de comandos . Quiero esto para mejorar mi conocimiento sobre cómo usar la línea de comandos (sin pasar por las manpáginas). Hay muchas cosas que hago a través de la GUI que no hago a través de la línea de comandos (algunas potencialmente automatizables a través de un script o atajos de teclado) y tener este archivo de registro sería una buena manera de aprenderlas.

Soy consciente de la existencia del archivo syslog, /var/logpero eso no es lo que necesito. La aplicación Activity Log Manager de los repositorios de Ubuntu no muestra el formato de línea de comandos, que yo sepa. Necesito algo como el archivo .bash_history que existe en mi carpeta de inicio pero que registra mis actividades basadas en GUI.


fuente
puedes usar una herramienta como strace para echar un vistazo a un programa en ejecución y ver qué sistema hace, sin embargo, esto generará grandes cantidades de datos
Amias
Si está buscando un programa que simplemente registre el nombre binario de los programas que se abren en la GUI, puedo hacerlo en un script. Si es lo que quieres, avísame. Sería mejor si aclaras cuáles son tus requisitos, así que edita tu pregunta. Grabar actividades basadas en GUI, como hacer clic en botones o abrir una nueva pestaña en un navegador, no es algo que se pueda grabar fácilmente, porque no están conectadas a comandos de shell reales
Sergiy Kolodyazhnyy
@Serg El registro que sugiera sería sin duda lo que estoy buscando. Algo así como un registro de "Administrador de tareas" basado en nombres CLI en lugar de nombres GLI, que, como sugiere la respuesta existente, puede no coincidir. Por ejemplo, si abro "Soporte de idiomas" en Configuración, quiero saber su equivalente de CLI. Etc ...
@luchonacho OK, comenzaré a escribir hoy, publicaré cuando esté listo. Por cierto, el "Soporte de idiomas" en Configuración no tiene cli equivalente. Algunas de las cosas, como el menú bluetooth o el menú de fondo, sí se pueden especificar unity-control-center backgroundo gnome-control-center background(dependiendo de su escritorio, Unity o XFCE o GNOME). Pero el mundo exterior probablemente solo verágnome-control-center
Sergiy Kolodyazhnyy
Hay muchas, muchas maneras de averiguar qué tarea realizan las aplicaciones GUI y cuál es su cli equivalente. Me parece bastante ineficiente tratar de registrar a ciegas todo lo que sucede por la fuerza bruta, asegurándome de que no atraparás todo. Mejor averigüe en casos específicos, utilizando herramientas específicas.
Jacob Vlijm

Respuestas:

2

Introducción

Si bien no es posible registrar todas las acciones de la GUI, se pueden hacer cosas como los comandos de registro que corresponden a ventanas abiertas. A continuación se muestra el script simple de Python que hace el trabajo. Todavía está en desarrollo, pero realiza el 90% de la tarea requerida.

Código fuente

#!/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()

Prueba de funcionamiento:

$ ./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

El script muestra la marca de tiempo, el tipo de evento, el PID de la ventana y el comando correspondiente.

Cómo utilizar

Se aplican las reglas estándar de cualquier script. Asegúrese de almacenar el script en el ~/bindirectorio. Si no tiene un ~/bindirectorio, cree uno. Guarde el archivo de script allí y asegúrese de que sea ejecutable con chmod +x ~/bin/log_open_windows.py. Después de eso, puede ejecutarlo desde la línea de comandos en cualquier momento que lo desee llamando ~/log_open_windows.pya la línea de comandos.

Sergiy Kolodyazhnyy
fuente
Gracias. ¡Parece prometedor! Dos preguntas. ¿Cómo ejecutarlo? ¿Qué falta el 10%?
¡Hábil! +1 de mi parte!
Fabby
@luchonacho agregué un párrafo sobre el uso. Le recomendaría que lo use manualmente desde la línea de comandos como lo describí. Puede hacer que se inicie automáticamente al inicio, pero no recomiendo hacerlo. El 10% que falta son otras pocas características que quería agregar, pero no creo que las vaya a agregar. Funciona lo suficientemente bien por ahora. Pero tal vez cambie de opinión otra vez
Sergiy Kolodyazhnyy
Esto es probablemente lo más cerca que puede llegar a lo que estaba buscando, a sabiendas de que no existe la solución perfecta. ¡Gracias!
4

¡Proponer ese tipo de archivo de registro como base para el aprendizaje es realmente una idea brillante!

Afortunadamente, muchas acciones de los programas GUI se implementan en el programa en sí, sin usar comandos externos; E incluso si usa comandos externos, puede ser de una manera diferente a la que se haría en un shell;
Entonces eso no existe, y no es fácil de implementar.

Pero tengo una solución para una parte del problema: el nombre del programa en la GUI a veces difiere del nombre del programa que uno necesita saber para un comando de shell, no solo si el nombre de la GUI está traducido a un idioma local.

Por ejemplo, ¿cómo iniciar el programa Filesen la línea de comando?

Necesitamos buscar en todos los *.desktoparchivos el nombre. Allí, encontramos el comando en la Execlínea:

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

enumera los nombres de archivos de escritorio y los comandos para el programa GUI File; reemplácelos con el nombre exacto que busca, incluso si son varias palabras (para la búsqueda de subcadenas, omita el =y $).

Con el comando, encuentro Filespuede ser nautilus, dolphino 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
fuente
Mmm, mi pregunta subyace a una vista de Linux de una complejidad escalada, donde los programas más elaborados se basan en un código más simple, por lo que pensé que cualquier aplicación GUI se basa en comandos de terminal, pero podría no ser el caso, ya que el terminal se basa en código bash, mientras que el software podría escribirse en python o c ++ o etc. ¿Me equivoco?
Las capas de complejidad existen, pero de una manera diferente: de manera rutinaria, hay llamadas al sistema, funciones de biblioteca y, además, una interfaz gráfica de usuario o una interfaz de línea de comando: son alternativas.
Volker Siegel