例如,我通常从应用程序菜单打开 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
可能是nautilus
,dolphin
或者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
。