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.