Can I see in a log file all GUI based tasks in its alternative command-line format?

Solution 1:

Proposing that kind log file as base for learning is actually a brilliant idea!

Unfourtunately, many actions of GUI programs are implemented in the program itself, not using external commands; And even if it uses external commands, it may be in a different way than one would do it in a shell;
So that does not exist, and is not easy to implement.

But I have a solution for a part of the problem: The program name in the GUI is sometimes differen from the program name one needs to know for a shell command - not only if the GUI name is translated to a local language.

For example, how to start the program Files in the comman line?

We need to look into all *.desktop files for the name. There, we find the command in the Exec line:

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

lists desktop file names and commands for the GUI program File - replace that with the exact name you look for - even it it's multiple words (for substring search, leave out the = and $).

With the command, I find Files may be nautilus, dolphin or 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

Solution 2:

Introduction

While it's not possible to log all GUI actions, such things as logging commands that correspond to open windows can be done. Below is the simple python script that does the job. It's still in development, but does 90% of the required task.

Source code

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

Test run:

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

The script shows timestamp, event type, the window PID, and the corresponding command.

How to use

The standard rules of any script apply. Make sure you store the script in ~/bin directory. If you don't have ~/bin directory , then create one. Save script file there and ensure it is executable with chmod +x ~/bin/log_open_windows.py. After than you can run it from command line at any time you wish by calling ~/log_open_windows.py in command-line.