Czy mogę zobaczyć w pliku dziennika wszystkie zadania oparte na GUI w alternatywnym formacie wiersza poleceń?

9

Na przykład zwykle otwieram podkładkę pod mysz (xfce odpowiednik gedit) z menu aplikacji. Wiem jednak, że możesz to zrobić również w terminalu, pisząc mousepad.

Idąc za tym przykładem, chcę, aby za każdym razem, gdy otwieram podkładkę pod mysz za pomocą GUI, nowy plik jest zapisywany w pliku dziennika, podając coś takiego Sep 5 15:35:11 lucho@lucho:~$ mousepad. Mówiąc bardziej ogólnie, chcę rejestrować wszystkie działania GUI, które są potencjalnie możliwe do wykonania za pośrednictwem wiersza polecenia (takie jak otwieranie programów, zmiana uprawnień, modyfikowanie ustawień systemowych itp.), Ale napisane w alternatywnym formacie wykonywania wiersza polecenia . Chcę tego, aby poprawić swoją wiedzę na temat korzystania z wiersza polecenia (bez przechodzenia między manstronami). Jest wiele rzeczy, które robię za pomocą GUI, których nie robię za pomocą wiersza poleceń (niektóre potencjalnie automatyzowane za pomocą skryptu lub skrótów klawiaturowych) i posiadanie tego pliku dziennika byłoby dobrym sposobem na ich poznanie.

Jestem świadomy istnienia pliku syslog, /var/logale nie tego potrzebuję. Aplikacja Activity Log Manager z repozytoriów Ubuntu, o ile wiem, nie wyświetla formatu wiersza poleceń. Potrzebuję czegoś takiego jak plik .bash_history, który istnieje w moim katalogu domowym, ale rejestruje moje działania oparte na GUI.


źródło
możesz użyć narzędzia takiego jak strace, aby zajrzeć do działającego programu i zobaczyć, jakie wywołuje system, wygeneruje to jednak ogromne ilości danych
Amias
Jeśli szukasz programu, który po prostu rejestruje binarną nazwę programów, które otwierają się w GUI, mogę to zrobić w skrypcie. Jeśli tego chcesz, daj mi znać. Byłoby lepiej, gdybyś wyjaśnił, jakie są twoje wymagania, więc edytuj swoje pytanie. Nagrywanie działań opartych na GUI, takich jak klikanie przycisków lub otwieranie nowej karty w przeglądarce, nie jest czymś, co można łatwo nagrać, ponieważ nie są one powiązane z rzeczywistymi poleceniami powłoki
Sergiy Kolodyazhnyy
@Erg Log, który sugerujesz, byłby z pewnością tym, czego szukam. Coś w rodzaju dziennika „Menedżera zadań” opartego na nazwach CLI zamiast nazwach GLI, które, jak sugeruje istniejąca odpowiedź, mogą się nie pokrywać. Na przykład, jeśli otworzę „Wsparcie językowe” w Ustawieniach, chcę znać jego odpowiednik CLI. Itd ...
@luchonacho OK, zacznę pisać dzisiaj, opublikuję, gdy będzie gotowy. Nawiasem mówiąc, „Obsługa języków” w Ustawieniach nie ma własnego odpowiednika cli. Niektóre rzeczy, takie jak menu Bluetooth lub menu w tle, robią - możesz określić unity-control-center backgroundlub gnome-control-center background(w zależności od pulpitu, Unity lub XFCE lub GNOME). Ale świat zewnętrzny prawdopodobnie tylko zobaczygnome-control-center
Sergiy Kolodyazhnyy
Istnieje wiele, wiele sposobów, aby dowiedzieć się, jakie zadanie są wykonywane przez aplikacje GUI i dowiedzieć się, jaki jest ich odpowiednik cli. Wydaje mi się dość nieskuteczne, aby próbować na ślepo rejestrować wszystko, co dzieje się brutalną siłą, mając pewność, że nie złapiecie wszystkiego. Lepiej dowiedz się w konkretnych przypadkach, używając określonych narzędzi.
Jacob Vlijm

Odpowiedzi:

2

Wprowadzenie

Chociaż nie można zarejestrować wszystkich działań GUI, można wykonać takie czynności, jak rejestrowanie poleceń odpowiadających otwartym oknom. Poniżej znajduje się prosty skrypt Pythona, który wykonuje to zadanie. Jest wciąż w fazie rozwoju, ale wykonuje 90% wymaganego zadania.

Kod źródłowy

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

Testowe uruchomienie:

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

Skrypt pokazuje znacznik czasu, typ zdarzenia, PID okna i odpowiednie polecenie.

Jak używać

Obowiązują standardowe zasady każdego skryptu. Upewnij się, że przechowujesz skrypt w ~/binkatalogu. Jeśli nie masz ~/binkatalogu, utwórz go. Zapisz plik skryptu i upewnij się, że jest wykonywalny chmod +x ~/bin/log_open_windows.py. Następnie możesz uruchomić go z wiersza poleceń w dowolnym momencie, wywołując ~/log_open_windows.pywiersz polecenia.

Sergiy Kolodyazhnyy
źródło
Dzięki. Wygląda obiecująco! Dwa pytania. Jak to uruchomić? Czego brakuje 10%?
Sprytne! +1 ode mnie!
Fabby
@luchonacho Dodałem akapit dotyczący użytkowania. Polecam używać go ręcznie z wiersza polecenia, jak to opisano. Możesz ustawić, aby uruchamiał się automatycznie przy uruchomieniu, ale nie polecam tego robić. Brakujące 10% to kilka innych funkcji, które chciałem dodać, ale nie sądzę, żebym je dodał. Na razie działa wystarczająco dobrze. Ale może znów zmienię zdanie
Sergiy Kolodyazhnyy
Prawdopodobnie jest to najbliżej tego, czego szukałem, świadomie, że idealne rozwiązanie nie istnieje. Dzięki!
4

Proponowanie tego rodzaju pliku dziennika jako podstawy do nauki jest naprawdę świetnym pomysłem!

Niestety, wiele działań programów GUI jest realizowanych w samym programie, bez użycia zewnętrznych poleceń; I nawet jeśli korzysta z zewnętrznych poleceń, może być w inny sposób niż w powłoce;
Tak więc nie istnieje i nie jest łatwe do wdrożenia.

Ale mam rozwiązanie części problemu: nazwa programu w GUI jest czasem inna niż nazwa programu, którą należy znać dla polecenia powłoki - nie tylko, jeśli nazwa GUI jest przetłumaczona na język lokalny.

Na przykład, jak uruchomić program Filesw linii komend?

Musimy sprawdzić *.desktopnazwę dla wszystkich plików. Tam znajdujemy polecenie w Execwierszu:

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

wyświetla nazwy plików na pulpicie i polecenia dla programu GUI File- zamień je dokładnie taką nazwą, której szukasz - nawet jeśli jest to wiele słów (w przypadku wyszukiwania podciągów pomiń =i $).

Z poleceniem, znajdę Filesmoże być nautilus, dolphinlub 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
źródło
Mmm, moje pytanie leży u podstaw linuksa o przeskalowanej złożoności, w którym bardziej rozbudowane programy są oparte na prostszym kodzie, więc pomyślałem, że każda aplikacja GUI opiera się na poleceniach terminalu, ale może nie być tak, ponieważ terminal jest oparty na kodzie bash, podczas gdy oprogramowanie może być napisane w Pythonie, C ++ itp. Czy się mylę?
Warstwy złożoności istnieją, ale w inny sposób: zwykle są to wywołania systemowe, funkcje biblioteczne, a na górze albo graficzny interfejs użytkownika, albo interfejs wiersza poleceń - są alternatywami.
Volker Siegel,