我可以在日志文件中看到其替代命令行格式的所有基于GUI的任务吗?


9

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

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

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


您可以使用诸如strace之类的工具来查看正在运行的程序,并查看它所执行的操作,尽管这样做会生成大量数据
Amias

如果您正在寻找一个仅记录在GUI中打开的程序的二进制名称的程序,则可以在脚本中执行。如果您要这样,请告诉我。如果您弄清楚您的实际需求会更好,所以请编辑您的问题。记录基于GUI的活动(例如单击按钮或在浏览器中打开新标签页)不是容易记录的事情,因为这些活动未与实际的shell命令关联
Sergiy Kolodyazhnyy

@Serg您建议的日志肯定是我正在寻找的日志。类似于基于CLI名称而不是GLI名称的“任务管理器”日志,正如现有答案所暗示的那样,该日志可能不一致。例如,如果我在“设置”中打开“语言支持”,则想知道其CLI等效项。等等...

@luchonacho好,我今天开始写,准备好后发布。顺便说一句,“设置”中的“语言支持”没有对应的CLI。您可以指定unity-control-center backgroundgnome-control-center background(取决于桌面,Unity或XFCE或GNOME)来执行某些操作,例如蓝牙菜单或背景菜单。但外界可能只会看到gnome-control-center
Sergiy Kolodyazhnyy

有很多很多方法可以找出GUI应用程序完成的任务,并找出它们的CLI等效项。对我来说,盲目记录暴力破解发生的所有事情似乎效率很低,以确保您不会捕获所有内容。使用特定工具更好地找出特定情况。
Jacob Vlijm '17

Answers:


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在命令行中调用从命令行运行它。


谢谢。看起来很有前途!两个问题。怎么运行呢?丢失的10%是多少?

好漂亮!向我+1!
Fabby

@luchonacho我在用法上添加了一段。我建议您按照我的描述从命令行手动使用它。您可以使其在启动时自动启动,但我不建议您这样做。缺少的10%是我想添加的其他一些功能,但我认为我不会添加它们。目前它已经足够好了。但也许我会再次改变主意
Sergiy Kolodyazhnyy

众所周知,这可能是您所寻找的最接近的解决方案,因为完美的解决方案并不存在。谢谢!

4

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

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

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

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

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

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

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

随着命令,我觉得Files可能是nautilusdolphinactive-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

嗯,我的问题是对Linux的复杂程度的看法,在Linux上,更复杂的程序是基于更简单的代码构建的,所以我认为任何GUI应用程序都依赖于终端命令,但情况并非如此,因为终端基于bash代码而软件可以用python或c ++等编写。我错了吗?

确实存在复杂性层,但是以不同的方式存在:很糟糕,有系统调用,库函数,并且图形用户界面或命令行界面位于顶部–它们是替代方法。
Volker Siegel 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.