我是否可以在日志文件中以备选命令行格式查看所有基于 GUI 的任务?

我是否可以在日志文件中以备选命令行格式查看所有基于 GUI 的任务?

例如,我通常从应用程序菜单打开 mousepad(xfce 中相当于 gedit)。但是,我知道您也可以在终端中输入 来执行此操作mousepad

按照这个例子,我想要的是每当我通过 GUI 打开 mousepad 时,日志文件中都会写入一个新行,内容类似于Sep 5 15:35:11 lucho@lucho:~$ mousepad。更一般地说,我想要的是记录所有可能通过命令行执行的 GUI 活动(如打开程序、更改权限、修改系统设置等),但以其替代的命令行执行格式编写。我希望通过这个来提高我对如何使用命令行的了解(无需翻阅页面man)。我通过 GUI 做了很多事情,而这些事情我不会通过命令行来做(有些可以通过脚本或键盘快捷键自动完成),而拥有这个日志文件将是学习它们的好方法。

我知道 syslog 文件的存在,/var/log但这不是我需要的。据我所知,Ubuntu 存储库中的活动日志管理器应用程序不显示命令行格式。我需要类似 .bash_history 文件的东西,它存在于我的主文件夹中,但记录我的基于 GUI 的活动。

答案1

提出将这种日志文件作为学习的基础实际上是一个绝妙的主意!

不幸的是,GUI 程序的许多动作都是在程序本身中实现的,而不是使用外部命令;而且即使它使用外部命令,也可能与在 shell 中执行的方式不同;
所以这是不存在的,并且不容易实现。

但是我对部分问题有一个解决方案:GUI 中的程序名称有时与 shell 命令需要知道的程序名称不同 - 不仅仅是将 GUI 名称翻译成当地语言。

例如如何Files在命令行中启动程序?

我们需要查看所有*.desktop文件中的名称。在那里,我们找到了以下Exec行中的命令:

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

列出 GUI 程序的桌面文件名和命令File- 将其替换为您要查找的确切名称 - 即使它是多个单词(对于子字符串搜索,请省略=and $)。

使用命令,我发现Files可能是nautilusdolphin或者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

答案2

介绍

虽然无法登录全部可以执行 GUI 操作,例如记录与打开的窗口相对应的命令。下面是执行该任务的简单 Python 脚本。它仍在开发中,但已完成所需任务的 90%。

源代码

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

测试运行:

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

脚本显示时间戳、事件类型、窗口 PID 和相应的命令。

如何使用

任何脚本的标准规则都适用。确保将脚本存储在~/bin目录中。如果没有~/bin目录,请创建一个。将脚本文件保存在那里并确保它可以使用执行chmod +x ~/bin/log_open_windows.py。之后,您可以随时通过调用命令行从命令行运行它~/log_open_windows.py

相关内容