Posso ver em um arquivo de log todas as tarefas baseadas em GUI em seu formato de linha de comando alternativo?


9

Por exemplo, normalmente abro o mousepad (equivalente ao xedit do gedit) no menu de aplicativos. No entanto, eu sei que você também pode fazer isso em um terminal digitando mousepad.

Seguindo este exemplo, o que eu quero é sempre que abro o mousepad via GUI, uma nova linha é gravada em um arquivo de log informando algo como Sep 5 15:35:11 lucho@lucho:~$ mousepad. Em geral, o que eu quero é registrar todas as atividades da GUI potencialmente executáveis ​​via linha de comando (como abrir programas, alterar permissões, modificar configurações do sistema etc.), mas escritas em seu formato alternativo de execução de linha de comando . Quero isso para melhorar meu conhecimento de como usar a linha de comando (sem passar pelas manpáginas). Há muitas coisas que faço através da GUI que não faço via linha de comando (algumas potencialmente automatizáveis ​​por meio de um script ou atalhos de teclado) e ter esse arquivo de log seria uma boa maneira de aprendê-las.

Estou ciente da existência do arquivo syslog, /var/logmas não é disso que preciso. O aplicativo Activity Log Manager dos repositórios Ubuntu não mostra o formato da linha de comando, até onde eu sei. Preciso de algo como o arquivo .bash_history que existe na minha pasta pessoal, mas registrando minhas atividades baseadas em GUI.


você pode usar uma ferramenta como o strace para espiar um programa em execução e veja o que as chamadas do sistema que faz, isso vai gerar grandes quantidades de dados embora
Amias

Se você está procurando um programa que simplesmente registra o nome binário dos programas abertos na GUI, eu posso fazer isso em um script. Se é o que você quer, me avise. Seria melhor se você esclarecesse quais são seus requisitos, por isso edite sua pergunta. Gravação de atividades baseadas em GUI, como clicar em botões ou abrir nova aba em um navegador não é algo que pode ser facilmente gravado, porque estes não estão ligados a comandos shell reais
Sergiy Kolodyazhnyy

@Serg O log que você sugere seria certamente o que estou procurando. Algo como um log do "Gerenciador de Tarefas" baseado nos nomes da CLI, em vez dos nomes da GLI, que, como sugerem as respostas existentes, podem não coincidir. Por exemplo, se eu abrir "Suporte ao idioma" em Configurações, quero saber seu equivalente na CLI. Etc ...

@luchonacho OK, vou começar a escrever hoje, postarei quando estiver pronto. A propósito, o "Suporte ao Idioma" em Configurações não possui um certificado equivalente. Algumas das coisas, como o menu bluetooth ou o menu background, fazem - você pode especificar unity-control-center backgroundou gnome-control-center background(dependendo da área de trabalho, Unity ou XFCE ou GNOME). Mas o mundo exterior provavelmente só verá #gnome-control-center
Sergiy Kolodyazhnyy

Existem muitas, muitas maneiras de descobrir qual tarefa é executada pelos aplicativos da GUI e descobrir qual é o seu equivalente de CLI. Parece-me bastante ineficiente tentar gravar cegamente tudo o que acontece por força bruta, tendo certeza de que você não pegará tudo. Melhor descobrir em casos específicos, usando ferramentas específicas.
Jacob Vlijm

Respostas:


2

Introdução

Embora não seja possível registrar todas as ações da GUI, é possível executar comandos de log que correspondem a janelas abertas. Abaixo está o script python simples que faz o trabalho. Ainda está em desenvolvimento, mas faz 90% da tarefa necessária.

Código fonte

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

Execução de teste:

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

O script mostra o registro de data e hora, o tipo de evento, o PID da janela e o comando correspondente.

Como usar

As regras padrão de qualquer script se aplicam. Certifique-se de armazenar o script no ~/bindiretório Se você não tiver um ~/bindiretório, crie um. Salve o arquivo de script e verifique se ele é executável chmod +x ~/bin/log_open_windows.py. Depois, você pode executá-lo na linha de comando a qualquer momento, chamando ~/log_open_windows.pyna linha de comando.


Obrigado. Parece promissor! Duas questões. Como executá-lo? O que faltam 10%?

Bacana! +1 de mim!
precisa saber é

@luchonacho Adicionei um parágrafo sobre o uso. Eu recomendaria que você o usasse manualmente na linha de comando, como descrevi. Você pode iniciar automaticamente na inicialização, mas eu não recomendo fazer isso. Os 10% que faltam são outros recursos que eu gostaria de adicionar, mas acho que não vou adicioná-los. Funciona bem o suficiente por enquanto. Mas talvez eu mude de idéia novamente
Sergiy Kolodyazhnyy

Este é provavelmente o mais próximo que você pode chegar do que eu estava procurando, sabendo que a solução perfeita não existe. Obrigado!

4

Propor esse tipo de arquivo de log como base para o aprendizado é realmente uma ideia brilhante!

Infelizmente, muitas ações dos programas da GUI são implementadas no próprio programa, sem usar comandos externos; E mesmo que use comandos externos, pode ser de uma maneira diferente do que se faria em um shell;
Portanto, isso não existe e não é fácil de implementar.

Mas eu tenho uma solução para uma parte do problema: o nome do programa na GUI às vezes é diferente do nome do programa que você precisa saber para um comando do shell - não apenas se o nome da GUI for traduzido para um idioma local.

Por exemplo, como iniciar o programa Filesna linha comman?

Precisamos procurar em todos os *.desktoparquivos o nome. Lá, encontramos o comando na Execlinha:

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

lista nomes de arquivos da área de trabalho e comandos para o programa GUI File- substitua-o pelo nome exato que você procura - mesmo que seja várias palavras (para pesquisa de substring, deixe de fora o =e $).

Com o comando, acho que Filespode ser 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

Mmm, minha pergunta é subjacente a uma visão do linux de uma complexidade escalada, onde programas mais elaborados são construídos com código mais simples, então eu pensei que qualquer aplicativo GUI dependia de comandos do terminal, mas pode não ser o caso, pois o terminal é baseado no código do bash, enquanto o software poderia ser escrito em python ou c ++ ou etc. Estou errado?

As camadas de complexidade existem, mas de uma maneira diferente: geralmente existem chamadas de sistema, funções de biblioteca e, além disso, uma interface gráfica do usuário ou uma interface de linha de comando - elas são alternativas.
Volker Siegel
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.