Posso vedere in un file di registro tutte le attività basate sulla GUI nel suo formato di riga di comando alternativo?


9

Ad esempio, normalmente apro mousepad (equivalente xfce di gedit) dal menu delle applicazioni. Tuttavia, so che puoi anche farlo in un terminale digitando mousepad.

Seguendo questo esempio, quello che voglio è ogni volta che apro mousepad tramite GUI, una nuova riga è scritta in un file di registro che afferma qualcosa del genere Sep 5 15:35:11 lucho@lucho:~$ mousepad. Più in generale, ciò che desidero è registrare tutte le attività della GUI che sono potenzialmente realizzabili tramite la riga di comando (come l'apertura di programmi, la modifica delle autorizzazioni, la modifica delle impostazioni di sistema, ecc.) Ma sono scritte nel suo formato alternativo di esecuzione della riga di comando . Lo voglio per migliorare la mia conoscenza di come usare la riga di comando (senza passare attraverso le manpagine). Ci sono molte cose che faccio attraverso la GUI che non faccio tramite riga di comando (alcune potenzialmente automatizzabili tramite uno script o tramite scorciatoie da tastiera) e avere questo file di registro sarebbe un buon modo per impararle.

Sono a conoscenza dell'esistenza del file syslog /var/logma non è quello di cui ho bisogno. Per quanto ne so, l'app Activity Log Manager dai repository Ubuntu non mostra il formato della riga di comando. Ho bisogno di qualcosa come il file .bash_history che esiste nella mia cartella home ma che registra le mie attività basate sulla GUI.


puoi usare uno strumento come strace per sbirciare in un programma in esecuzione e vedere quale sistema chiama, tuttavia questo genererà enormi quantità di dati
Amias,

Se stai cercando un programma che registra semplicemente il nome binario dei programmi che si aprono nella GUI, posso farlo in uno script. Se è quello che vuoi, fammi sapere. Sarebbe meglio se chiarissi quali sono i tuoi requisiti, quindi modifica la tua domanda. Registrare attività basate sulla GUI, come fare clic sui pulsanti o aprire una nuova scheda in un browser non è qualcosa che può essere facilmente registrato, perché questi non sono collegati ai comandi della shell effettivi
Sergiy Kolodyazhnyy,

@Serg Il registro che suggerisci sarebbe sicuramente quello che sto cercando. Qualcosa di simile a un registro "Task Manager" basato sui nomi CLI anziché sui nomi GLI, che, come suggerisce la risposta esistente, potrebbe non coincidere. Ad esempio, se apro "Supporto lingua" in Impostazioni, voglio conoscere il suo equivalente CLI. Ecc ...

@luchonacho OK, inizierò a scrivere oggi, pubblicherò quando sarà pronto. A proposito, "Supporto per la lingua" in Impostazioni non ha un suo equivalente. Alcune cose, come il menu bluetooth o il menu di sfondo, lo fanno - è possibile specificare unity-control-center backgroundo gnome-control-center background(a seconda del desktop, Unity o XFCE o GNOME). Ma il mondo esterno probabilmente vedrà solognome-control-center
Sergiy Kolodyazhnyy il

Esistono molti, molti modi per scoprire quale compito viene svolto dalle applicazioni della GUI e scoprire qual è il loro equivalente cli. Mi sembra abbastanza inefficiente provare a registrare ciecamente tutto ciò che accade con la forza bruta, assicurandomi che non prenderai tutto. Meglio scoprirlo in casi specifici, usando strumenti specifici.
Jacob Vlijm,

Risposte:


2

introduzione

Sebbene non sia possibile registrare tutte le azioni della GUI, è possibile eseguire operazioni come la registrazione di comandi che corrispondono a finestre aperte. Di seguito è riportato il semplice script Python che fa il lavoro. È ancora in fase di sviluppo, ma svolge il 90% dell'attività richiesta.

Codice sorgente

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

Prova:

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

Lo script mostra il timestamp, il tipo di evento, il PID della finestra e il comando corrispondente.

Come usare

Si applicano le regole standard di qualsiasi script. Assicurati di archiviare lo script nella ~/bindirectory. Se non si dispone di una ~/bindirectory, crearne una. Salva lì il file di script e assicurati che sia eseguibile con chmod +x ~/bin/log_open_windows.py. Dopo di che puoi eseguirlo dalla riga di comando in qualsiasi momento desideri chiamando ~/log_open_windows.pynella riga di comando.


Grazie. Sembra promettente! Due domande. Come eseguirlo? Qual è il 10% mancante?

Nifty! +1 da me!
Fabby,

@luchonacho Ho aggiunto un paragrafo sull'utilizzo. Consiglierei di usarlo manualmente dalla riga di comando come ho descritto. Puoi farlo avviare automaticamente all'avvio, ma non ti consiglio di farlo. Il 10% mancante sono altre poche funzionalità che volevo aggiungere, ma non credo che le aggiungerò. Funziona abbastanza bene per ora. Ma forse cambierò di nuovo idea
Sergiy Kolodyazhnyy il

Questo è probabilmente il più vicino a quello che stavo cercando, sapendo che la soluzione perfetta non esiste. Grazie!

4

Proporre quel tipo di file di registro come base per l'apprendimento è in realtà un'idea geniale!

Sfortunatamente, molte azioni dei programmi della GUI sono implementate nel programma stesso, non usando comandi esterni; E anche se utilizza comandi esterni, potrebbe essere in un modo diverso rispetto a quello che si farebbe in una shell;
Quindi non esiste e non è facile da implementare.

Ma ho una soluzione per una parte del problema: il nome del programma nella GUI è talvolta diverso dal nome del programma che uno deve conoscere per un comando shell - non solo se il nome della GUI è tradotto in una lingua locale.

Ad esempio, come avviare il programma Filesnella riga di comando?

Dobbiamo cercare tutti i *.desktopfile per il nome. Lì, troviamo il comando nella Execriga:

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

elenca i nomi dei file desktop e i comandi per il programma GUI File- sostituiscilo con il nome esatto che cerchi - anche se si tratta di più parole (per la ricerca di sottostringa, tralasciare =e $).

Con il comando, trovo che Filespossa essere nautilus, dolphinoppure 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

Mmm, la mia domanda è alla base di una visione di Linux di una complessità scalata, in cui programmi più elaborati sono basati su un codice più semplice, quindi ho pensato che qualsiasi applicazione GUI si basasse su comandi di terminale ma potrebbe non essere il caso poiché il terminale si basa su codice bash mentre il software potrebbe essere scritto in python o c ++ o ecc. Sbaglio?

Gli strati di complessità esistono, ma in un modo diverso: rougnamente, ci sono chiamate di sistema, funzioni di libreria e in cima un'interfaccia utente grafica o un'interfaccia della riga di comando - sono alternative.
Volker Siegel,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.